文章目录

  • 前言
  • 一、springboot项目导入依赖包
  • 二、模板创建
  • 1.模板语法
  • 2.项目模板
  • 三、报错
  • 1.调用接口报错
  • 2.解决方法
  • 3.模板路径问题
  • 四、附录(部分代码)
  • 总结



前言

利用easypoi做模板excel文件导出,遇到了一些问题,做一下总结。


一、springboot项目导入依赖包



<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.1</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.1</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-base</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-web</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.7</version>
</dependency>

二、模板创建

1.模板语法



空格分割
三目运算 {{test ? obj:obj2}}
n: 表示 这个cell是数值类型 {{n:}}
le: 代表长度{{le:()}} 在if/else 运用{{le:() > 8 ? obj1 : obj2}}
fd: 格式化时间 {{fd:(obj;yyyy-MM-dd)}}
fn: 格式化数字 {{fn:(obj;###.00)}}
fe: 遍历数据,创建row
!fe: 遍历数据不创建row
$fe: 下移插入,把当前行,下面的行全部下移.size()行,然后插入
#fe: 横向遍历
v_fe: 横向遍历值
!if: 删除当前列 {{!if:(test)}}
单引号表示常量值 ‘’: 比如’1’ 那么输出的就是 1
&NULL&: 空格
]] :换行符 多行遍历导出
sum: 统计数据

2.项目模板



java easy poi java easy poi 模版导出内存溢出_java


说明:

{{templateName}}{{merge:cal:le:(colList)+1}} :表示生成的表格名称进行单元格合并操作,合并单元格长度组装参数的到的colList集合长度+1;
{{#fe: colList t.name}} :表示获取字段名写入到excel时进行横向遍历写入;

三、报错

1.调用接口报错

NestedServletException: Handler dispatch failed; nested 
exception is java.lang.NoSuchMethodError: 
org.apache.poi.ss.usermodel.Cell.getCellType()Lorg/apac
he/poi/ss/usermodel/CellType

2.解决方法

查了资料可能原因:1.模板路径错误;2.版本不兼容,easypoi(4.2.0)与poi(3.17)版本不兼容;

分析了一下发现:如果是模板路径有问题导致模板找不到,Workbook workbook = ExcelExportUtil.exportExcel(params, map);
获取到的workbook将为空值,报503未知异常;
尝试将poi、poi-ooxml的版本号又3.17改为4.1.1后问题得到了解决。

3.模板路径问题

模板文件路径试了一下,只能配置成绝对路径,尝试用classpath相对路径无法获取到模板;

绝对路径:

java easy poi java easy poi 模版导出内存溢出_idea_02

相对路径:

template:

path1: classpath:templates/excelTemplate_0122.xlsx

java easy poi java easy poi 模版导出内存溢出_数据_03

四、附录(部分代码)

实现类:

@Override
    public void excelExport(HttpServletResponse response, String templateId) throws Exception{
        if (this.getById(templateId)==null){
            throw new BusinessException("模板id不存在");
        }
        DataReportTemplateEntity templateEntity = this.getById(templateId);
        String templateName = templateEntity.getTemplateName();
        //读取模板字段表
        List<DataReportTemplateColumnEntity> templateColumnEntities = templateColumnMapper.getColumnByTemplateId(templateId);
        log.info(templatePath);
        //调用easypoi进行模板输出
        TemplateExportParams params = new TemplateExportParams(templatePath);
        params.setColForEach(true);
        //确保输入输出顺序一致
        Map<String, Object> map = new LinkedHashMap();
        map.put("templateName", templateName);
        //组装生成excel所需参数
        List<Map<String,Object>> colList = new ArrayList();
        for (DataReportTemplateColumnEntity entity : templateColumnEntities){
            Map<String, Object> objectMap = new LinkedHashMap<>();
            //这里的字段名称和模板中对应
            objectMap.put("name",entity.getColumnName());
            objectMap.put("colDesc",entity.getColumnDesc());
            colList.add(objectMap);
        }
        log.info(colList.toString());
        map.put("colList",colList);
        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        String fileName = templateName + System.currentTimeMillis() + ".xlsx";
        //调用文件下载工具类中的方法,设置header,文件输出流将数据写入模板
        FileDownloadUtil.fileDownload(response,fileName,workbook);

fileDownload方法:

public static void fileDownload(HttpServletResponse response, String fileName, Workbook wb) throws Exception {
		fileName = URLEncoder.encode(fileName, "utf-8");
 		response.reset();// 清空输出流
		response.setHeader("content-Type",
                    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		response.setCharacterEncoding("utf-8");
    	response.setHeader("Content-Disposition", "attachment;filename="+
                new String(fileName.getBytes("utf-8"), "ISO-8859-1"));
        setResponseHeader(response, fileName);
        OutputStream os = response.getOutputStream();
        wb.write(os);
        os.flush();
        os.close();
        wb.close();
    }

总结

照葫芦画瓢,遇到问题多尝试几种方法!