编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

EasyExcel文件导出错误解决(easyexcel导出文件到本地)

wxchong 2024-08-24 01:52:45 开源技术 7 ℃ 0 评论

## EasyExcel文件导出错误解决

最近在做一个项目,有将记录导出Excle的需求,采用了阿里的EasyExcel工具,导出功能学习很快,很快参考网站上的代码和官网上资料搞定,并且开发环境(windows)使用非常正常,但是上传到内网测试服务器后,导出总是从异常处退回,服务器端也没有什么信息,这个坑费了和2天时间,特记录下来与大家共享。

## 一、 先上代码

服务器站代码如下,这段代码使用官网代码一致,只是修改了数据:

```java

List<QuarantineExport> quarantineExports = employeeService.quarantineExportData(company, department, selectCodeColor, selectQuarState);

String fileName = URLEncoder.encode("健康码统计信息.xls", "UTF-8");

try {

response.setContentType("application/vnd.ms-excel");

response.setCharacterEncoding("utf-8");

// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系

String fileName = URLEncoder.encode("健康码统计信息", "UTF-8");

response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

// 这里需要设置不关闭流

EasyExcel.write(response.getOutputStream(), QuarantineExport.class)

.autoCloseStream(Boolean.FALSE)

.sheet("隔离信息")

.doWrite(employeeService.quarantineExportData(company, department,selectCodeColor,selectQuarState));

} catch (Exception e) {

// 重置response

response.reset();

response.setContentType("application/json");

response.setCharacterEncoding("utf-8");

Map<String, String> map = new HashMap<String, String>();

map.put("status", "failure");

map.put("message", "下载文件失败" + e.getMessage());

response.getWriter().println(JSON.toJSONString(map));

}

```

前端代码,我有两种模式调整,一种是用按钮直接调URL简单调用,另一种是用ajax和jqery组合复杂条件调用,代码如下。

```javascript

var department = $('#departmentList').val();

var selectCodeColor = $('#selectCodeColor').val();

var selectQuarState = $('#selectQuarState').val();

var url = "/statListExport?department="+department+"&selectCodeColor="+selectCodeColor+"&selectQuarState="+selectQuarState;

$.ajax({

type: "get",

async: true,

url: url,

contentType: "application/vnd.ms-excel",

success: function (data) {

console.log(data);

},

error: function (errorMsg) {

//请求失败时执行该函数

alert("导出失败!");

}

})

```

## 二、错误现象

在开发环境使用非常正常,没有任何问题,上传到测试环境服务器不能导出文件,总是产生一个 "下载文件失败" 的json文件,查了很多资料都没有找到方法。

首先,从前端分析错误,这时从前端控制台上发现有一个警告信息,

Resource interpreted as Document but transferred with MIME type application/msexcel:

以为是后台传输正常,到测试服务器环境后这个原因导致的,在这个问题上搞了我一整天,按了4种前端接受后台文件方法,代码贴出来,给大家分享一下。

```javascript

//这3条是从表单取查询条件

var department = $('#departmentList').val();

var selectCodeColor = $('#selectCodeColor').val();

var selectQuarState = $('#selectQuarState').val();

//w合成后台GET数据的URL,这儿把参数合在一起了,也可以用dataForm或json字符串

var url = "/statListExport?department="+department+"&selectCodeColor="+selectCodeColor+"&selectQuarState="+selectQuarState;

//方法一:

var xhr = new XMLHttpRequest();

xhr.open('Get', url, true);

xhr.responseType = "blob"; // 返回类型blob

xhr.onload = function () {

if (this.status === 200) {

var blob = this.response;

var reader = new FileReader();

reader.readAsDataURL(blob); // 转换为base64,可以直接放入a表情href

reader.onload = function (e) {

var a = document.createElement('a');

a.download = '健康码统计信息.xlsx';//下载文件名

a.href = e.target.result;

$("body").append(a); // 修复firefox中无法触发click

a.click();

$(a).remove();

}

}

};

// 发送ajax请求

xhr.send()

//方法二:

var a = document.createElement('a');

a.setAttribute("href",url);

a.click();

document.body.removeChild(a);*/

//方法三

var iframe = document.createElement('iframe');

iframe.id = "IFRAMEID";

iframe.style.display = 'none';

document.body.appendChild(iframe);

iframe.src = url;

iframe.addEventListener("load", function () {

console.log("FILE LOAD DONE.. Download should start now");

});

//方法四:

$.ajax({

type: "get",

async: true,

url: url,

contentType: "application/vnd.ms-excel",

success: function (data) {

console.log(data);

},

error: function (errorMsg) {

//请求失败时执行该函数

alert("导出失败!");

}

})

```

从上面代码看,有四种方法可以从后台获取语言件流,供后续使用。这四种方未能分别都试过,原来以为前后端文件流格式不一样导致,由于开发环境没这个问题,只有生产环境有。开发环境与测试环境不一样真是问题大啊,整了一天都没有找到答案。

前端找不到答案只能继续在后台找,第二天折腾后台代码,网上打到一个旧的案例,死马当活马医,试试看,没想到用旧的代码虽然一堆过时的警告,上传到测试环境服务服务器竟然工作了,泪奔啊,代码如下,供大家参考:

```java

List<QuarantineExport> quarantineExports = employeeService.quarantineExportData(company, department, selectCodeColor, selectQuarState);

String fileName = URLEncoder.encode("健康码统计信息.xls", "UTF-8");

//写excel文件

ExcelWriter writer = null;

OutputStream outputStream = response.getOutputStream();

try {

//添加响应头信息

response.setHeader("Content-disposition", "attachment; filename=" + fileName);

response.setContentType("application/msexcel;charset=UTF-8");

response.setHeader("Pragma", "No-cache");

response.setHeader("Cache-Control", "no-cache");

response.setDateHeader("Expires", 0);

//实例化 ExcelWriter

writer = new ExcelWriter(outputStream, ExcelTypeEnum.XLS, true);

//实例化表单

Sheet sheet = new Sheet(1, 0, QuarantineExport.class);

sheet.setSheetName("隔离信息");

//输出

writer.write(quarantineExports, sheet);

writer.finish();

outputStream.flush();

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

response.getOutputStream().close();

} catch (IOException e) {

e.printStackTrace();

}

}

```

## 三、问题原因

搞了一天都没搞定,找到了EasyExcel钉钉群,刚好EasyExcel作之一庄家钜在群中解签问题,在此感谢作都的提示。

作都提示open jdk存在字体不全的问题,可能导致类似问题。

又找了一圈,没有解决问题的头绪,网上有一个说是将生产环境换为oracle JdK,哎,oracle JDK修订版不是免费的啊,这是一个写着玩的项目,算了,继续用过时的方法吧。

注意这个过时的方法导出的excel文件是低版本的,够用了,文件扩展名只能为xls,不要用xlsx否则打不开。

如正式要用,还是将open jdk字体安装全,或都用oracle jdk吧。这是恢复编程学习以来遇到最大的一个坑,坑了我2天时间,特记录。

老伍。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表