通過POI導出的 Excel 文件,在打開時報錯,測試了一下,發現在低版本的 Office 中(2003版,配合2007格式兼容包)打開正常,但在高版本 Office 中,會報以下錯誤:
發現“XXX.xlsx”中的部分內容有問題。是否讓我們盡量嘗試恢復?如果您信任此工作簿的源,請單擊“是”。
點擊 “否” 就不打開文件了,點擊 “是” 之后可以打開文件,出現以下提示:
通過修復或刪除不可讀取的內容,Excel 已能夠打開該文件。
...
Excel 已完成文件級驗證和修復。此工作簿的某些部分可能已被修復或丟棄。
同一個文件用WPS打開則正常,但我們不可能要求用戶都用WPS,這不現實。
上網搜了一下,試了好幾種方案,看看哪一種能解決問題(我是通過第二種解決的!!)。
方法一:在獲得 workbook.Write(ms) 生成的 MemoryStream 后,使用了 ms.GetBuffer() 返回文件內容,導致生成的 Excel 文件結尾處有大量的 00(空字節),改為 ms.ToArray() 即可得到正常的文件了。
問題在於 window excel 凍結窗口只能設置一行, WPS可以設置多行
設置凍結窗口如下: 凍結第一行
sheet.createFreezePane(0, 1, 0, 1); // 凍結單元格
下面對CreateFreezePane的參數作一下說明:
第一個參數表示要凍結的列數;
第二個參數表示要凍結的行數,這里只凍結列所以為0;
第三個參數表示右邊區域可見的首列序號,從1開始計算;
第四個參數表示下邊區域可見的首行序號,也是從1開始計算,這里是凍結列,所以為0;
方法二:在響應頭設置導出內容的長度
String fileName = new String("測試Excel".getBytes("gb2312"), "ISO8859-1"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); workbook.write(baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); response.setHeader("Content-Length", String.valueOf(bais.available())); response.addHeader("Content-Disposition", "attachment;filename=" + fileName + IdUtil.fastSimpleUUID() + ".xlsx"); OutputStream os = response.getOutputStream(); byte[] b = new byte[1024]; while ((bais.read(b)) > 0) { os.write(b); } bais.close();
os.flush(); os.close();