easyPoi export form (template replacement and annotation generation)

Simplified version

template replacement data

    /**
     * 前端下载Excel
     *
     * @param response
     * @param activityQueryVo
     */
    @Override
    public void export(HttpServletResponse response, ActivityQueryVo activityQueryVo) {
    
    
        try {
    
    
            Map<String, Object> data = getData(activityQueryVo);
            Workbook workbook = export(templateUrl, data);
            String fileName = "返回给前端的文件名";
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

Tools

    /**
     * 模板数据替换
     *
     * @param templateUtl 模板路径
     * @param map 数据集合
     * @return
     * @throws IOException
     */
    private Workbook export(String templateUtl, Map<String, Object> map) throws IOException {
    
    
        File file = new File(templateUtl);
        String canonicalPath = file.getCanonicalPath();
        // 默认为false, 设置sheetName为true, 开启多sheet,
        TemplateExportParams params = new TemplateExportParams(canonicalPath, true);
        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        return workbook;
    }

data preparation

        Map<String, Object> allMap = new HashMap<String, Object>();

        List<Map<String, Object>> list0 = Lists.newArrayList();
        Map<String, Object> map = new HashMap<String, Object>();
        // 添加多个map
        map.put("peopleNumber", 100);
        // 如果有多处需要循环输出的数据, 就添加多个list
        list0.add(map);
        allMap.put("list", list0);

data style

   {
    
    
    "msg": "操作成功",
    "code": 200,
    "data": {
    
    
        "list": [
            {
    
    
                "venueCategory": "",
                "peopleNumber": 100,
                "num": 1,
                "activityName": "非常",
                "organizers": "道济四等奖",
                "activityType": "",
                "holdTime": "2022-02-06"
            },
            {
    
    
                "venueCategory": "",
                "peopleNumber": 15,
                "num": 2,
                "activityName": "测试2",
                "organizers": "啊啊啊啊",
                "activityType": "",
                "holdTime": "2022-03-24"
            },
            {
    
    
                "venueCategory": "",
                "peopleNumber": 250,
                "num": 3,
                "activityName": "测试A",
                "organizers": "维众",
                "activityType": "",
                "holdTime": "2022-09-07"
            }
        ]
    }
}

Template description:
cyclic data is wrapped with { { KaTeX parse error: Expected 'EOF', got '}' at position 18: ...: collection name t. field name}̲} where { { fe: }} is unchanged , t is easypoi's default cycle identifier
insert image description here

Note generation Excel

Annotate entities

    @Excel(name = "场馆类别", needMerge = true)
    private String venueCategory;

Tools

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.vxdata.activity.entity.CulturalActivity;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 *
 */
@Slf4j
@Component
public class EasyPoiUtil {
    
    
    public void exportExcel(List<CulturalActivity> list) throws IOException {
    
    
        String outUrl = "D:\\Excel\\527.xls";
        List<CulturalActivity> newList = list;

        //获取导出参数
        ExportParams exportParams = new ExportParams("人均接受文化场馆服务次数专项活动汇总表(1-12月)", "报送单位:", ExcelType.XSSF);
        //设置导出样式
        exportParams.setStyle(ExcelStyleUtil.class);
        //设置行高
        exportParams.setHeight((short) 6);

        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, CulturalActivity.class, list);

        // 获取到workbook对象之后设置每列列宽
        Sheet sheet = workbook.getSheetAt(0);
//        sheet.setColumnWidth(3, 30 * 256);
//        sheet.setColumnWidth(5, 30 * 256);

        // 动态设置行高
        for(int i = 0; i <= sheet.getLastRowNum(); i ++) {
    
    
            Row row = sheet.getRow(i);
            setRowHeight(row);
        }

        FileOutputStream outputStream = new FileOutputStream(new File(outUrl));
        workbook.write(outputStream);
        outputStream.close();
    }

    private static void setRowHeight(Row row){
    
    
        //根据内容长度设置行高
        int enterCnt = 0;
        for(int j = 0; j < row.getPhysicalNumberOfCells(); j ++) {
    
    
            int rwsTemp = row.getCell(j).toString().length();
            //这里取每一行中的每一列字符长度最大的那一列的字符
            if (rwsTemp > enterCnt) {
    
    
                enterCnt = rwsTemp;
            }
        }
        //设置默认行高为35
        row.setHeightInPoints(35);
        //如果字符长度大于35,判断大了多少倍,根据倍数来设置相应的行高
        if (enterCnt>35){
    
    
            float d = enterCnt/35;
            float f = 35*d;
            if (d>2 && d<4){
    
    
                f = 35*2;
            }else if(d>=4 && d<6){
    
    
                f = 35*3;
            }else if (d>=6 && d<8){
    
    
                f = 35*4;
            }
            row.setHeightInPoints(f);
        }
    }

}

complex version

Tools:

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.vxdata.common.config.VxdataConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
 
/**
 * @Auther: HeJD
 * @Date: 2018/10/9 13:54
 * @Description:
 */
@Slf4j
public class EasyPoiUtil {
    
    
 
    /**
     * 功能描述:复杂导出Excel,包括文件名以及表名。创建表头
     *
     * @author HeJD
     * @date 2018/10/9 13:54
     * @param list 导出的实体类
     * @param title 表头名称
     * @param sheetName sheet表名
     * @param pojoClass 映射的实体类
     * @param isCreateHeader 是否创建表头
     * @param fileName
     * @param response
     * @return
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) {
    
    
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setCreateHeadRows(isCreateHeader);
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }
 
 
    /**
     * 功能描述:复杂导出Excel,包括文件名以及表名,不创建表头
     *
     * @author HeJD
     * @date 2018/10/9 13:54
     * @param list 导出的实体类
     * @param title 表头名称
     * @param sheetName sheet表名
     * @param pojoClass 映射的实体类
     * @param fileName
     * @param response
     * @return
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) {
    
    
        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
    }


    /**
     * 功能描述:Map 集合导出
     *
     * @author HeJD
     * @date 2018/10/9 13:54
     * @param list 实体集合
     * @param fileName 导出的文件名称
     * @param response
     * @return
     */
    public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
    
    
        defaultExport(list, fileName, response);
    }
 
    /**
     * 功能描述:默认导出方法
     *
     * @author HeJD
     * @date 2018/10/9 13:54
     * @param list 导出的实体集合
     * @param fileName 导出的文件名
     * @param pojoClass pojo实体
     * @param exportParams ExportParams封装实体
     * @param response
     * @return
     */
    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
    
    
        exportParams.setStyle(ExcelStyleUtil.class);
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
    
    
            downLoadExcel(fileName, response, workbook);
        }
    }
 
    /**
     * 功能描述:Excel导出
     *
     * @author HeJD
     * @date 2018/10/9   15:35
     * @param fileName 文件名称
     * @param response
     * @param workbook Excel对象
     * @return
     */
    private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
    
    
        ServletOutputStream outputStream = null;
        try {
    
    
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(fileName, "UTF-8") );
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
    
    
            throw new  RuntimeException(e);
        }
    }

    /**
     * 导出到若依的本地目录
     * @param list 实体集合
     * @param title 表头名称
     * @param sheetName sheet表名
     * @param pojoClass 映射的实体类
     * @param fileName 文件名
     */
    public static void exportExcelToLocal(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName) {
    
    
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setStyle(ExcelStyleUtil.class);
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
    
    
            // 本地资源路径
            String localPath = VxdataConfig.getDownloadPath();
            File savefile = new File(localPath);
            if (!savefile.exists()) {
    
    
                savefile.mkdirs();
            }
            FileOutputStream fos = null;
            try {
    
    
                String excelName = localPath + fileName;
                fos = new FileOutputStream(excelName);
                workbook.write(fos);
                fos.close();
                log.debug("export Excel Success: {}", fileName);
            } catch (FileNotFoundException e) {
    
    
                e.printStackTrace();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
    }
 
    /**
     * 功能描述:默认导出方法
     *
     * @author HeJD
     * @date 2018/7/23 15:33
     * @param list 导出的实体集合
     * @param fileName 导出的文件名
     * @param response
     * @return
     */
    private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
    
    
        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
        if (workbook != null) ;
        downLoadExcel(fileName, response, workbook);
    }
 
 
    /**
     * 功能描述:根据文件路径来导入Excel
     *
     * @author HeJD
     * @date 2018/10/9 14:17
     * @param filePath 文件路径
     * @param titleRows 表标题的行数
     * @param headerRows 表头行数
     * @param pojoClass Excel实体类
     * @return
     */
    public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
    
    
        //判断文件是否存在
        if (StringUtils.isBlank(filePath)) {
    
    
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
    
    
            list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        } catch (NoSuchElementException e) {
    
    
            throw new RuntimeException("模板不能为空");
        } catch (Exception e) {
    
    
            e.printStackTrace();
 
        }
        return list;
    }
 
    /**
     * 功能描述:根据接收的Excel文件来导入Excel,并封装成实体类
     *
     * @author HeJD
     * @date 2018/10/9 14:17
     * @param file 上传的文件
     * @param titleRows 表标题的行数
     * @param headerRows 表头行数
     * @param pojoClass Excel实体类
     * @return
     */
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
    
    
        if (file == null) {
    
    
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
    
    
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        } catch (NoSuchElementException e) {
    
    
            throw new RuntimeException("excel文件不能为空");
        } catch (Exception e) {
    
    
            throw new RuntimeException(e.getMessage());
 
        }
        return list;
    }
 
 
}

Style configuration:

import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;

public class ExcelStyleUtil implements IExcelExportStyler {
    
    
   // 数据行类型
   private static final String DATA_STYLES = "dataStyles";
   // 标题类型
   private static final String TITLE_STYLES = "titleStyles";
   //数据行样式
   private CellStyle styles;
   // 标题样式
   private CellStyle titleStyle;

   public ExcelStyleUtil(Workbook workbook) {
    
    
       this.init(workbook);
   }

   private void init(Workbook workbook) {
    
    
       this.styles = initStyles(workbook);
       this.titleStyle = initTitleStyle(workbook);
   }


   @Override
   public CellStyle getHeaderStyle(short i) {
    
    
       return null;
   }

   /**
    * 标题样式
    */
   @Override
   public CellStyle getTitleStyle(short i) {
    
    
       return titleStyle;
   }

   @Override
   public CellStyle getStyles(boolean parity, ExcelExportEntity entity) {
    
    
       return styles;
   }

   /**
    * 获取样式方法
    *
    * @param dataRow 数据行
    * @param obj     对象
    * @param data    数据
    */
   @Override
   public CellStyle getStyles(Cell cell, int dataRow, ExcelExportEntity entity, Object obj, Object data) {
    
    
       return getStyles(true, entity);
   }

   @Override
   public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams) {
    
    
       return null;
   }


   /**
    * 初始化--标题行样式
    * @param workbook
    * @return
    */
   private CellStyle initTitleStyle(Workbook workbook) {
    
    
       return buildCellStyle(workbook,TITLE_STYLES);
   }

   /**
    * 初始化--数据行样式
    * @param workbook
    * @return
    */
   private CellStyle initStyles(Workbook workbook) {
    
    
       return buildCellStyle(workbook,DATA_STYLES);
   }

   /**
    * 设置单元格样式
    * @param workbook
    * @param type 类型  用来区分是数据行样式还是标题样式
    * @return
    */
   private CellStyle buildCellStyle(Workbook workbook,String type) {
    
    
       CellStyle style = workbook.createCellStyle();
//        // 字体样式
//        Font font = workbook.createFont();
//        if(TITLE_STYLES.equals(type)){
    
    
//            font.setFontHeightInPoints((short)12);
//            font.setBold(true);
//        }
//        if(DATA_STYLES.equals(type)){
    
    
//            font.setFontHeightInPoints((short)10);
//        }
//        font.setFontName("Courier New");
//        style.setFont(font);
       // 设置底边框
//        style.setBorderBottom(BorderStyle.THIN);
//        // 设置左边框
//        style.setBorderLeft(BorderStyle.THIN);
//        // 设置右边框;
//        style.setBorderRight(BorderStyle.THIN);
//        // 设置顶边框;
//        style.setBorderTop(BorderStyle.THIN);
//        // 设置底边颜色
//        style.setBottomBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
//        // 设置左边框颜色;
//        style.setLeftBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
//        // 设置右边框颜色;
//        style.setRightBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
//        // 设置顶边框颜色;
//        style.setTopBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
       // 设置自动换行;
       style.setWrapText(false);
       // 设置水平对齐的样式为居中对齐;
       style.setAlignment(HorizontalAlignment.CENTER);
       // 设置垂直对齐的样式为居中对齐;
       style.setVerticalAlignment(VerticalAlignment.CENTER);
       return style;
   }
}

use:

EasyPoiUtil.exportExcelToLocal(数据集合list, 表头名称,sheet表名, 实体.class,  输出文件全路径);

org.apache.poi version conflict with easypoi and poi-tl

Correct version correspondence:

  1. easypoi : 4.1.0
  2. org.apache.poi :4.1.0
  3. poi-tl : 1.6.0

The initial business is to generate word files, using poi-tl to generate, my poi-tl version is 1.5.0

        <!--poi-tl生成word-->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.5.0</version>
        </dependency>

The corresponding org.apache.poi version is 3.16
insert image description here
, but then Excel needs to be generated. I use easypoi version 4.1.0

        <!--easypoi Excel导出-->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.1.0</version>
        </dependency>

At this time, I reported an error when I was executing Excel.

org.apache.poi.ss.usermodel.Cell.getCellType()Lorg/apache/poi/ss/usermodel/CellType

java.lang.ClassNotFoundException: org.apache.poi.poifs.filesystem.FileMagic

I checked that the version of org.apache.poi is too low and needs to be replaced with version 3.8 or above, so I replaced org.apache.poi with version 4.1.0, but at this time poi-tl reported an error saying that the version does not match

Solution: Upgrade poi-tl to version 1.6.0 and org.apache.poi to version 4.1.0

        <!--poi-tl生成word-->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.6.0</version>
        </dependency>

The org.apache.poi used by the 1.5.0 version of poi-tl is 3.16, and the 1.6.0 version of poi-tl corresponds to the 4.1.0 version of org.apache.poi
insert image description here

Guess you like

Origin blog.csdn.net/qq_44154912/article/details/122927928