NIUCLOUD是一款SaaS管理后台框架多应用插件+云编译。上千名开发者、服务商正在积极拥抱开发者生态。欢迎开发者们免费入驻。一起助力发展! 广告
# POI Excel ## Excel write ### ***实现功能*** - 无限层级表头 - 数据行合并 - 合计 - 数据超长自动分sheet(excel单个sheet最大导出2^32=65536条数据【程序可配调整单个sheet最大条数】) - 多table分sheet - 自定义导出样式 ### ***工具路径*** - 工具实现 :zonetop.gisboot.core.common.utils.poi.ExcelWriteUtils - Excel配置:zonetop.gisboot.core.common.model.poi.ExcelConfigModel - 表头单元格配置:zonetop.gisboot.core.common.model.poi.ExcelCellModel ### ***参数解析*** - ExcelConfigModel: 导出execl总体配置(等于号后内容都是默认配置) ``` String fileName = "excel"; //"文件名" String title = "报表导出"; //"标题",未空时不显示table的title private int maxSheetSize = ExcelConstant.MAX_SHEET_SIZE;//"每个sheet的最大条数" 取值范围【(表头+title)高度*20~2^32】 IndexedColors foreColor = IndexedColors.BLACK;// "前景色" 字颜色 IndexedColors background = IndexedColors.LIGHT_YELLOW;//"背景色" short titlePoint = 20;//"标题字号",字体 大小 short titleHeight = 48;// "标题高度" title单元格高度 String titleFont = "微软雅黑"; // "标题字体",暂时未使用 short headPoint = 16;// "列头字号" 表头字体大小 short headHeight = 36;// "列标题高度" String headFont = "微软雅黑";// "列头字体",暂时未使用 short dataHeight = 32;//"数据行高度" 数据的行高 boolean isTotal = true;//"是否合计" ,为true时会默认增加序号列 List<ExcelCellModel> cells;// excel导出的table表头 具体如下个说明 ``` - ExcelCellModel: 数据单元格配置 ``` String key; //"显示字段key" String title;// "显示title" String dict; //"字典key" excel工具不解析字典数据,这个字段为调用接口解析字典数据使用 String type = ExcelConstant.STRING_TYPE; //"数据类型 number/string/date" 只有数字类型会统计 Boolean isDisplay = true;// "是否可见,默认可见" private String width = "0";//"无自适应" 表头的宽,先读取的数据,无/0 的话再读取minWidth private String minWidth = "100";//最小宽度,当width设置为0自适应的时候,需要提供一个最小非0宽度,其他情况和width保持一 private String align = "center";// 数据的对齐方式 left/center/right" 表头/title永远居中 IndexedColors foreColor = IndexedColors.BLACK;// "前景色" 数据的字体颜色, IndexedColors background = IndexedColors.WHITE;// "背景色" 数据的背景色 short point = 14; //"列头字号" 数据的字体大小 String font = "微软雅黑"; // "列头字体" 暂未使用 int top = 0;// "单元格上" 表头展示位置 ,配置无效,由工具自动计算 int bottom = 0;//"单元格下" 表头展示位置 ,配置无效,由工具自动计算 int left = 0;//"单元格左" 表头展示位置 ,配置无效,由工具自动计算 int right = 0;// "单元格右" 表头展示位置 ,配置无效,由工具自动计算 List<ExcelCellModel> children = null; //"多层结构" 复杂表头的子表头数据 ``` ### ***提供接口*** #### description:对外只提供一个 ***exportExcel*** 接口,根据不同的重载实现不同的需求 - 单sheet,json数据导出 ``` /** * 导出excel 单个sheet * * @param basePath 导出地址,文件夹路径 * @param config excel配置 * @param data 数据 [{a:"xxx"},{a:"",b:"xxx",children:[{c:"x"},{c:"xx"}]}],父子表属性同名需区分 * @return excel 导出的全路径地址 * @throws Exception 异常 */ public static String exportExcel(String basePath, ExcelConfigModel config, JSONArray data) ``` - 多sheet,json数据导出 (单个sheet导出excel 为数据封装一下后调用多sheet方法) ``` * 导出excel 多个sheet/兼容单个 * * @param basePath 生成文件文件夹地址 * @param configList excel配置列表 * @param dataList 动态数据 [[{a:"xxx"},{a:"",b:"xxx",children:[{c:"x"},{c:"xx"}]}]],父子表属性同名需区分 * @return 导出的全路径地址 * @throws Exception 异常 */ public static String exportExcel(String basePath, List<ExcelConfigModel> configList, List<JSONArray> dataList) ``` - 单sheet T数据导出(暂未实现:需要实现表头翻译注解,目前仅实现到简单的对象,且未实现注解解析) ``` /** * 通用导出excel 未实现 * * @param basePath 生成文件地址 * @param config excel配置 * @param dataList excel 数据 父子表需要含有children * @param <T> 泛型 * @return 文件地址 */ public static <T> String exportExcel(String basePath, ExcelConfigModel config, List<T> dataList) ``` ### ***示例代码*** - 前端 ~~~ <template> <Card> <gis-table ref="gisTable" :column="tableColumns" :searchRule="searchRule" height="auto" v-on="listener" :buttons="buttons" :fetchName="portalFeedback.getByCondition" @handleCustomParam="handleCustomParam" v-model="data" /> </Card> </template> <script> import { portalFeedback } from "~/api";//业务接口 import { formMixin, dictColorMixin } from "@/core/mixins"; import fileStream from "@/core/libs/fileStream.js"; export default { components: {}, mixins: [formMixin, dictColorMixin], data() { return { portalFeedback, item: "", tableColumns: [],//table 的表头 data: [], listener: { handleBtnExport: this.handleBtnExport // excel 导出时间监听 }, //table 中excel导出按钮 buttons: [ { key: "export", title: "导出数据", icon: "md-download" } ], searchRule: []//查询过滤条件 }; }, methods: { handleBtnExport() { this.$gisExcelHeadModal({ title: "设置Excel表头信息", column: this.tableColumns, handleOk: e => { const params ={ title:JSON.stringify(e),//导出使用的excel header json ...this.$refs["gisTable"].searchData //导出过滤条件 } // 请求自实现导出excel接口(主要是获取数据,拼凑数据) this.postRequest(`${portalFeedback.exportFeedbackData}`, params).then(res => { //接口生产路径 及 文件名 if (res.success) { var config = {}; config["filePath"] = res.result.filePath; config["fileName"] = res.result.fileName; } //根据配置 下载文件 this.downloadRequest(`/files/fileDownloadByPath`, config).then( rest => { if (rest.type === "application/octet-stream") { //文件流返回值类型 const content = rest; fileStream.downloadStream(content, res.result.fileName); } else { this.$Message.warning("下载失败"); } } ); }); } }); } }, mounted() { } }; </script> <style></style> ~~~ - 后端 ~~~ package zonetop.gisboot.gis.controller.back; /** * 门户意见反馈 * * @author 黄文俊 * @version 1.0.0 * @date 2020-06-18 20:04:41 */ @Slf4j @RestController @Api(value = "门户意见反馈管理接口") @RequestMapping("/gisBoot/gis/back/portalFeedback") public class PortalFeedbackControllerBacker { @Resource private PortalFeedbackService portalFeedbackService; @Resource private FileServerService fileServerService; @Resource private SysGlobalConfigService sysGlobalConfigService; @RequestMapping(value = "/exportFeedbackData", method = RequestMethod.POST) @ApiOperation(value = "导出数据") public Result<Object> exportFeedbackData(@RequestParam String title, PortalFeedbackSearchModel portalFeedbackSearchModel) throws Exception { //根据过滤条件过滤数据 List<PortalFeedbackEntity> list = portalFeedbackService .list(getQuery(portalFeedbackSearchModel)); FileServerEntity serverEntity = fileServerService.getEntityByCode( sysGlobalConfigService.getServerCode(BizSystemConstant.FILE_LOCAL_URL)); //excel 生成的文件夹路径 String filePath = serverEntity.getUrl() + FileToUrlConstant.EXCEL; //文件名 String fileName = "意见反馈"; //excel 基础配置信息 提供4个参数的构造函数(文件名,title,是否合计、表头) ExcelConfigModel excelConfig = new ExcelConfigModel(fileName, fileName, false, JSONObject.parseArray(title, ExcelCellModel.class)); //excel 表头数据 List<ExcelCellModel> titleList = JSONObject.parseArray(title, ExcelCellModel.class); //字典转译【实现方式...】 List<ExcelCellModel> dictList = Linq.of(titleList).where(v -> v.getDict() != null).toList(); for (PortalFeedbackEntity entity : list) { for (ExcelCellModel excelCellModel : dictList) { //根据实体类名赋值 BeanUtils.setProperty(entity, excelCellModel.getKey(), DictUtil .readDictionary(BeanUtils.getProperty(entity, excelCellModel.getKey()), excelCellModel.getDict())); } } //生成excel 并返回excel文件的全路径 filePath = ExcelWriteUtils.exportExcel(filePath, excelConfig, JSONArray.parseArray(JSON.toJSONString(list))); //构造返回前端结果 JSONObject joResult = new JSONObject(); joResult.put("filePath", filePath); joResult.put("fileName", filePath.substring(filePath.lastIndexOf(fileName))); return new ResultUtil<>().isOk(joResult); } } ~~~ - ***导出结果*** ### ***静态调用测试*** - 静态测试代码 ~~~ public static void main(String[] args) throws Exception { //excel生成地址 String outPath = "C:\\Users\\demo\\Desktop\\"; //表头数据 JSONArray header = FileReaderUtils.readJsonArray( "E:\\SVN\\gis-boot-modules\\gis-boot-back\\gis-boot-core\\src\\main\\java\\zonetop\\gisboot\\core\\common\\utils\\poi\\testHeader.json"); List<ExcelCellModel> headerList = JSONArray.parseArray(header.toJSONString(), ExcelCellModel.class); //excel 导出数据 JSONArray data = FileReaderUtils.readJsonArray( "E:\\SVN\\gis-boot-modules\\gis-boot-back\\gis-boot-core\\src\\main\\java\\zonetop\\gisboot\\core\\common\\utils\\poi\\testData.json"); ExcelConfigModel config = new ExcelConfigModel(); config.setCells(headerList); //导出单个sheet excel(数据超长仍会分页) exportExcel(outPath, config, data); //导出多个sheet excel List<ExcelConfigModel> configList = new ArrayList<>(); configList.add(config); //第二个表头数据(勿直接使用同一表头对象当不同sheet的表头) JSONArray header2 = FileReaderUtils.readJsonArray( "E:\\SVN\\gis-boot-modules\\gis-boot-back\\gis-boot-core\\src\\main\\java\\zonetop\\gisboot\\core\\common\\utils\\poi\\testHeader.json"); List<ExcelCellModel> headerList2 = JSONArray.parseArray(header2.toJSONString(), ExcelCellModel.class); ExcelConfigModel config2 = new ExcelConfigModel(); config2.setCells(headerList2); configList.add(config2); List<JSONArray> dataList = new ArrayList<>(); dataList.add(data); dataList.add(data); exportExcel(outPath, configList, dataList); } ~~~ - ***生成效果*** ![](https://img.kancloud.cn/22/8e/228ede7940bef242cd42bbcf519b39da_595x870.png) ## Excel read