首先这是个Docker环境字体缺失或者其它文件缺失的问题
引言
在使用 EasyExcel 工具类进行导出时,突遇到一个神秘的错误:java.lang.InternalError: java.lang.reflect.InvocationTargetException
。这篇博客将为你详细解释如何修复这个错误,并分享我在排查问题时的心得体会。
问题描述
在使用以下 EasyExcel 工具类进行导出时,出现了一个导致生成的 Excel 文件为空的问题:
这是我当时使用的easyExcel方法
public static <T> void exportExcel(List<T> list, HttpServletResponse response, String sheetName, Class<T> clz) throws IOException {
try (OutputStream fileOutputStream = response.getOutputStream()) {
//文件以流形式返回前端下载
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码,所有通过后端的文件下载都可以如此处理
String fileName = URLEncoder.encode(sheetName, "UTF-8");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
response.flushBuffer();
//添加响应头信息
response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");
response.setContentType("application/msexcel;charset=UTF-8");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
ExcelWriter excelWriter = EasyExcel.write(fileOutputStream, clz)
//下面两行是自定义样式
// .registerWriteHandler(new CustomCellWriteUtil())
// .registerWriteHandler(getStyleStrategy())
.build();
WriteSheet sheet = EasyExcel.writerSheet(0, "导出数据").build();
excelWriter.write(list, sheet);
excelWriter.finish();
fileOutputStream.flush();
} catch (Exception e) {
e.printStackTrace();
log.error("导出失败: [{}]", e.getLocalizedMessage(), e);
}
}
问题排查
通过查看日志,发现导致问题的异常为反射失败,但在本地起服务连接 Nacos 后导出正常,而部署到 Docker 后导出的文件一直为空。
执行write的时候一直写出一个为空的xlsx文件,查了日志显示反射失败, 但有个很奇怪的点,本地起服务连nacos后导出正常,但部署到docker后导出的文件就一直为空.后面一直排错,包都打了几百个,日志都翻烂了,后面才恍然大悟有没有可能是docker没有我这个样式的字体
后面找到了我这个缺失的字体
RUN apk add --update ttf-dejavu fontconfig
加到DockerFile上后重新构建镜像启动容器后终于可以了
如果不想加入字体,也可以考虑将 JDK 镜像更换为
openjdk:11-jre-alpine
因为openjdk:11-jre-alpine更大一些,对于一些字体或其它的支持也更多一点,其它jdk版本同理。
FROM openjdk:11-jre-alpin
MAINTAINER ****************
RUN mkdir -p /data/{app,logs} && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/shanghai" > /etc/timezone;
RUN apk add --update ttf-dejavu fontconfig
WORKDIR /data/app
ADD energy-1.0.jar ./
EXPOSE 30010
ENTRYPOINT ["java","-jar", "-Dfile.encoding=utf-8", "./energy-1.0.jar","-XX:G1HeapRegionSize=16MB","-XX:-UseContainerSupport","-server","-XX:+UseStringDeduplication","-XX:+UseG1GC","-XX:+DisableExplicitGC", "-XX:-HeapDumpOnOutOfMemoryError","-XX:+AggressiveOpts"]
结语
通过本文的介绍,你学会了修复 EasyExcel 导出错误的方法,并解决了在 Docker 环境中可能出现的字体问题。希望这些经验能够帮助你更顺利地使用 EasyExcel 进行 Excel 导出,并在遇到类似问题时能够迅速解决。如果有其他问题或疑问,欢迎留言交流!