每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

Java导出Excel内容有问题_关于 NPOI 导出的 Excel 出现“部分内容有问题” 的解决方法

1. 问题描述

1. 通过POI导出的 Excel 文件,在打开时报错,测试了一下,发现在低版本的 Office 中(2003版,配合2007格式兼容包)打开正常,但在高版本 Office 中,会报以下错误:

发现“XXX.xlsx”中的部分内容有问题。是否让我们尽量尝试恢复?如果您信任此工作簿的源,请单击“是”。

2. 点击 “否” 就不打开文件了,点击 “是” 之后可以打开文件,出现以下提示:

通过修复或删除不可读取的内容,Excel 已能够打开该文件。

...

Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃。

3. 同一个文件用WPS打开则正常,但我们不可能要求用户都用WPS,这不现实。

上网搜了一下,试了好几种方案,看看哪一种能解决问题(我是通过第二种解决的!!)。

2. 解决方法

2.1 冻结单元格

1. 在获得 workbook.Write(ms) 生成的 MemoryStream 后,使用了 ms.GetBuffer() 返回文件内容,导致生成的 Excel 文件结尾处有大量的 00(空字节),改为 ms.ToArray() 即可得到正常的文件了。

2. 问题在于 window excel 冻结窗口只能设置一行, WPS可以设置多行

3. 设置冻结窗口如下: 冻结第一行

sheet.createFreezePane(0, 1, 0, 1); // 冻结单元格

4. 下面对CreateFreezePane的参数作一下说明

第一个参数表示要冻结的列数;

第二个参数表示要冻结的行数,这里只冻结列所以为0;

第三个参数表示右边区域可见的首列序号,从1开始计算;

第四个参数表示下边区域可见的首行序号,也是从1开始计算,这里是冻结列,所以为0;

2.2 在响应头设置导出内容的长度

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();

 

posted @ 2021-08-05 14:55  helloliyh  阅读(5507)  评论(0编辑  收藏  举报