前言
在开发Web应用的过程中,导出数据到Excel是一种常见的需求,尤其当数据量较大或者需要将不同类型的数据分开呈现时,使用多Sheet页签导出功能显得尤为重要。若依框架(RuoYi)提供了强大的工具类ExcelManySheetUtil
来帮助开发者轻松实现这一功能。
一、环境准备
确保项目中已经集成了若依框架的相关依赖。通常情况下,若依框架会自带一些常用的工具类和依赖项,比如ExcelManySheetUtil
。如果未集成,请按照官方文档添加相关依赖。
二、工具类详解
ExcelManySheetUtil
是若依框架提供的一个多Sheet导出工具类,它可以帮助我们快速地将多个数据集导出到同一个Excel文件的不同Sheet中。
package com.ruoyi.common.utils.poi;import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DeptUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.file.FileTypeUtils;
import com.ruoyi.common.utils.file.ImageUtils;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;/*** Excel多sheet导出工具** @author ruoyi*/
public class ExcelManySheetUtil
{private static final Logger log = LoggerFactory.getLogger(ExcelManySheetUtil.class);/*** Excel sheet最大行数,默认65536*/public static final int sheetSize = 65535;/*** 工作表名称*/private String fileName;/*** 导出类型(EXPORT:导出数据;IMPORT:导入模板)*/private Type type;/*** 工作薄对象*/private Workbook wb;/*** 工作表对象*/private Sheet sheet;/*** 样式列表*/private Map<String, CellStyle> styles;/*** 多sheet导出数据列表*/Map<String, List<?>> map;/*** 注解列表*/private List<Object[]> fields;/*** 最大高度*/private short maxHeight;/*** 统计列表*/private Map<Integer, Double> statistics = new HashMap<Integer, Double>();/*** 数字格式*/private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");/*** 实体对象*/public Class clazz;/*** 初始化,并创建Workbook* @param map* @param fileName*/public ExcelManySheetUtil(Map<String, List<?>> map, String fileName) {if(map == null){map = new LinkedHashMap<>();}this.map = map;this.fileName = fileName;this.type = Type.EXPORT;createWorkbook();}/*** 对list数据源将其里面的数据导入到excel表单** @param sheetNameMap 导出数据集合* @param classMap 工作表的名称* @return 结果*/public AjaxResult<Void> exportManySheetExcel(Map<String, String> sheetNameMap, Map<String, Class> classMap){AtomicInteger no = new AtomicInteger();map.forEach((k, v)->{this.clazz = classMap.get(k);createExcelField();// 取出一共有多少个sheet.double sheetNo = Math.ceil(v.size() / sheetSize);for (int index = 0; index <= sheetNo; index++){createSheet(sheetNo, no.get(), sheetNameMap.get(k) + (index==0?"":index));no.getAndIncrement();// 产生一行Row row = sheet.createRow(0);int column = 0;// 写入各个字段的列头名称for (Object[] os : fields){Excel excel = (Excel) os[1];this.createCell(excel, row, column++);}if (Type.EXPORT.equals(type)){fillExcelData(index, row, v);addStatisticsRow();}}});OutputStream out = null;try{String filename = encodingFilename(fileName);out = new FileOutputStream(getAbsoluteFile(filename));wb.write(out);return AjaxResult.success(filename);}catch (Exception e){log.error("导出Excel异常{}", e.getMessage());throw new CustomException("导出Excel失败,请联系网站管理员!");}finally{if (wb != null){try{wb.close();}catch (IOException e1){e1.printStackTrace();}}if (out != null){try{out.close();}catch (IOException e1){e1.printStackTrace();}}}}/*** 填充excel数据** @param index 序号* @param row 单元格行*/public void fillExcelData(int index, Row row, List<?> list){int startNo = index * sheetSize;int endNo = Math.min(startNo + sheetSize, list.size());for (int i = startNo; i < endNo; i++){row = sheet.createRow(i + 1 - startNo);// 得到导出对象.Object vo = list.get(i);int column = 0;for (