1. 前言
1.1 關(guān)于Excel的一般導(dǎo)出
- 一般列表導(dǎo)出以及個性化樣式設(shè)置請看下面的文章:
- JAVA導(dǎo)出Excel通用工具類——第一篇:詳細介紹POI 導(dǎo)出excel的多種復(fù)雜情況,包括動態(tài)設(shè)置篩選、動態(tài)合并橫向(縱向)單元格等多種復(fù)雜情況.
- JAVA導(dǎo)出Excel通用工具——第二篇:使用EasyExcel導(dǎo)出excel的多種情況的例子介紹.
2.2 關(guān)于easyexcel的根據(jù)模版導(dǎo)出
- 如果使用easy Excel的話,下面就不用看了,這個官網(wǎng)關(guān)于怎么使用以及例子提供的非常詳細,git上還能下載源碼,官網(wǎng)如下,使用不再介紹,具體看官網(wǎng)即可:
Easy Excel 之 填充excel.
2. 先看效果
2.1 模版
- 靜態(tài)填充簡單模版如下:
- 動態(tài)填充簡單模版:
- 單個list:
- 多個list:
- 單個list單條數(shù)據(jù):
- 單個list:
2.2 效果
- 靜態(tài)填充效果如下:
- 動態(tài)填充效果如下:
- 單個list:
- 多個list:
- 單個list單條數(shù)據(jù):
- 單個list:
3. 代碼實現(xiàn)(核心代碼)
3.1 項目代碼結(jié)構(gòu)
- 如下:
3.2 靜態(tài)填充例子代碼
- 工具類代碼已封裝,所以調(diào)用很簡單即可實現(xiàn),如下:
3.3 動態(tài)list填充代碼
- 單個list:
- 多個list
- 單個list單條數(shù)據(jù):
3.4 附核心代碼
3.4.1 object轉(zhuǎn)map工具類
-
MapObjectUtil.java 如下:
package com.liu.susu.excel.template.poi.common; import com.alibaba.fastjson.JSONObject; import com.liu.susu.excel.template.poi.example.data.DogEntity2; import org.apache.commons.beanutils.BeanMap; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Description * @Author susu * @Date 2024/2/19 */ public class MapObjectUtil { /** * @description: 將object的list數(shù)據(jù) 轉(zhuǎn)換成 map的list(如:List<Map<String, Object>>) * @param objDataList * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>> * @author susu */ public static List<Map<String, Object>> objListToMapList(List<?> objDataList){ List<Map<String, Object>> dataList = new ArrayList<>(); if (objDataList==null || objDataList.size()<1){ return null; } objDataList.forEach(obj->{ try { Map<String, Object> map = MapObjectUtil.objectToMap(obj); dataList.add(map); } catch (IllegalAccessException e) { throw new RuntimeException(e); } }); return dataList; } /** * @description: 將object數(shù)據(jù)轉(zhuǎn)換成map數(shù)據(jù) * @param obj * @return java.util.Map<java.lang.String,java.lang.Object> * @author susu */ public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException { Map<String, Object> map = new HashMap(); Class<?> cla = obj.getClass(); Field[] fields = cla.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); String keyName = field.getName(); Object value = field.get(obj); if (value == null) value = ""; map.put(keyName, value); } return map; } /** * @description: 使用 JSONObject 將object轉(zhuǎn)換成map * @param obj * @return java.util.Map<?,?> * @author susu */ public static Map<?, ?> objectToMap2(Object obj) { if (obj == null) return null; return JSONObject.parseObject(JSONObject.toJSONString(obj),Map.class); } /** * @description: 使用BeanMap將object轉(zhuǎn)換成map * @param obj * @return java.util.Map<?,?> * @author susu */ public static Map<?, ?> objectToMap3(Object obj) { if (obj == null) return null; return new BeanMap(obj); } public static void main(String[] args) { DogEntity2 dog = new DogEntity2(); dog.setDogId("A-1001"); dog.setDogAge(3); dog.setDogName("aaa"); // Map map = JSONObject.parseObject(JSONObject.toJSONString(dog),Map.class); Map map = objectToMap2(dog); System.out.println(map); } }
3.4.2 根據(jù)模版導(dǎo)出Excel程序代碼
-
ExcelTemplateProc.java 如下:
package com.liu.susu.excel.template.poi.common; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.CellCopyPolicy; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.util.ResourceUtils; import java.io.*; import java.util.List; import java.util.Map; /** * @Description 根據(jù)模版導(dǎo)出Excel程序 * @Author susu * @Date 2024/2/19 */ public class ExcelTemplateProc { /** * @param templateFileName * @param exportFilePathAndName * @param staticDataMap * @param dynamicDataMappingList * @return void * @description: 根據(jù)模版導(dǎo)出Excel入口 * @author susu * @date 2024/2/20 */ public static void doExportExcelByTemplateProc(String templateFileName, String exportFilePathAndName, Map<String, Object> staticDataMap, List<DynamicDataMapping> dynamicDataMappingList) throws IOException { /** * 1. 從resources下加載模板并替換 * 使用 ResourceUtils 加載文件 */ File file = ResourceUtils.getFile("classpath:"+templateFileName); InputStream inputStream = new FileInputStream(file); Workbook workbook = dealFirstSheetByTemplate(inputStream, staticDataMap, dynamicDataMappingList); // 2. 保存到本地 saveExportFile(workbook, exportFilePathAndName); } /** * @param workbook * @param excelFilePath * @return void * @description: 保存導(dǎo)出的Excel文件到服務(wù)器 * @author susu * @date 2024/2/20 */ public static void saveExportFile(Workbook workbook, String excelFilePath) throws IOException { FileOutputStream outputStream = new FileOutputStream(excelFilePath); executeWorkBookWrite(workbook, outputStream); } /** * @param workbook * @param outputStream * @return void * @description: 數(shù)據(jù)輸出 * @author susu * @date 2024/2/20 */ public static void executeWorkBookWrite(Workbook workbook, OutputStream outputStream) throws IOException { workbook.write(outputStream); outputStream.flush(); outputStream.close(); workbook.close(); } /** * @param inputStream * @param staticDataMap * @param dynamicDataMappingList * @return org.apache.poi.ss.usermodel.Workbook * @description: 處理只有一個sheet頁的模版 * @author susu * @date 2024/2/20 */ public static Workbook dealFirstSheetByTemplate(InputStream inputStream, Map<String, Object> staticDataMap, List<DynamicDataMapping> dynamicDataMappingList) throws IOException { XSSFWorkbook workbook = new XSSFWorkbook(inputStream); XSSFSheet sheet = workbook.getSheetAt(0); // 按模板處理sheet頁 dealSheetDataByTemplate(sheet, staticDataMap, dynamicDataMappingList); return workbook; } /** * @param sheet * @param staticDataMap * @param dynamicDataMappingList * @return void * @description: 按模板處理sheet頁里的數(shù)據(jù) * @author susu * @date 2024/2/19 */ private static void dealSheetDataByTemplate(XSSFSheet sheet, Map<String, Object> staticDataMap, List<DynamicDataMapping> dynamicDataMappingList) { // 循環(huán)sheet里每一行 for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) { XSSFRow row = sheet.getRow(i); DynamicDataMapping dynamicDataMapping = getDynamicRowDataByMatch(row, dynamicDataMappingList); if (dynamicDataMapping != null) { i = getTemplateLastRowIndexAfterDealTemplate(sheet, i, dynamicDataMapping); } else { dealTemplateDataRow(row, null, staticDataMap); } } } /** * @param row * @param dataMap * @param dataPrefix * @return void * @description: 循環(huán)處理模版中每行的數(shù)據(jù) * @author susu * @date 2024/2/20 */ private static void dealTemplateDataRow(XSSFRow row, String dataPrefix, Map<String, Object> dataMap) { if (dataMap == null) { return; } for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { XSSFCell cell = row.getCell(i); fillInTemplateCellDataValue(cell, dataPrefix, dataMap); } } /** * @param cell * @param dataPrefix * @param dataMap * @return void * @description: 填充模版里單元格的值 * @author susu * @date 2024/2/20 */ private static void fillInTemplateCellDataValue(XSSFCell cell, String dataPrefix, Map<String, Object> dataMap) { if (cell == null) { return; } String cellValue = cell.getStringCellValue();//獲取模版里設(shè)置的數(shù)據(jù) if (StringUtils.isEmpty(cellValue)) { return; } boolean flag = false; dataPrefix = StringUtils.isEmpty(dataPrefix) ? "" : (dataPrefix + "."); for (Map.Entry<String, Object> entry : dataMap.entrySet()) { // 循環(huán)所有,因為可能一行有多個占位符 String cellTemplateStr = "{{" + dataPrefix + entry.getKey() + "}}"; if (cellValue.contains(cellTemplateStr)) { // 替換模版中單元格的數(shù)據(jù) cellValue = cellValue.replace(cellTemplateStr, entry.getValue() == null ? "" : entry.getValue().toString()); flag = true; } } if (flag) { cell.setCellValue(cellValue); } } /** * @param row * @param dynamicDataMappingList * @return com.liu.susu.excel.template.poi.common.DynamicDataMapping * @description: 通過模版sheet中的行數(shù)據(jù) 與 動態(tài)數(shù)據(jù)匹配,獲取此行需要填充的動態(tài)數(shù)據(jù) * @author susu * @date 2024/2/21 */ private static DynamicDataMapping getDynamicRowDataByMatch(XSSFRow row, List<DynamicDataMapping> dynamicDataMappingList) { if (dynamicDataMappingList == null || dynamicDataMappingList.size() < 1) { return null; } for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) { XSSFCell cell = row.getCell(j); String value = cell.getStringCellValue(); if (value != null) { for (DynamicDataMapping dynamicData : dynamicDataMappingList) { if (value.startsWith("{{" + dynamicData.getDataId() + ".")) { return dynamicData; } } } } return null; } /** * @param sheet * @param rowIndex * @param dynamicDataMapping * @return int * @description: 根據(jù)動態(tài)數(shù)據(jù)的條數(shù)動態(tài)復(fù)制模版行,每處理一個類型的list返回最后的行數(shù),進而處理下一個類型的list * @author susu * @date 2024/2/20 */ private static int getTemplateLastRowIndexAfterDealTemplate(XSSFSheet sheet, int rowIndex, DynamicDataMapping dynamicDataMapping) { if (dynamicDataMapping == null) { return rowIndex; } int dataRows = dynamicDataMapping.getDataList().size(); // 需要拷貝的行數(shù)(因為模板行本身占1行,所以-1) int copyRows = dataRows - 1; if (copyRows > 0) { /** * shiftRows: 從動態(tài)數(shù)據(jù)模版行(rowIndex)到最后一行,這些全部行都向下移copyRows行 * 相當(dāng)于模版行上面插入n行空行(n=copyRows) */ sheet.shiftRows(rowIndex, sheet.getLastRowNum(), copyRows, true, false); // 拷貝策略 CellCopyPolicy cellCopyPolicy = makeCellCopyPolicy(); // 因為從模版行開始向下平移了copyRows行,所以這里 模板行=rowIndex + copyRows, int templateDataRow = rowIndex + copyRows; // 因為模版行上新增了空行,所以要把模板所在行的模版 拷貝到上面新增的空行 for (int i = 0; i < copyRows; i++) { //templateDataRow-模版行數(shù)據(jù) rowIndex + i循環(huán)的當(dāng)前空行 sheet.copyRows(templateDataRow, templateDataRow, rowIndex + i, cellCopyPolicy); } } // 循環(huán)模版行:動態(tài)替換模版行(將模版行里的模版替換成動態(tài)數(shù)據(jù)) for (int j = rowIndex; j < rowIndex + dataRows; j++) { Map<String, Object> dataMap = dynamicDataMapping.getDataList().get(j - rowIndex); dealTemplateDataRow(sheet.getRow(j), dynamicDataMapping.getDataId(), dataMap); } return rowIndex + copyRows; } /** * @param * @return org.apache.poi.ss.usermodel.CellCopyPolicy * @description: 拷貝策略 * @author susu * @date 2024/2/20 */ public static CellCopyPolicy makeCellCopyPolicy() { CellCopyPolicy cellCopyPolicy = new CellCopyPolicy(); cellCopyPolicy.setCopyCellValue(true); cellCopyPolicy.setCopyCellStyle(true); return cellCopyPolicy; } }
3.4.3 導(dǎo)出工具類入口代碼
-
ExportExcelByTemplateUtils.java 如下:
package com.liu.susu.excel.template.poi.common; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Description 根據(jù)模版導(dǎo)出Excel工具類 * @Author susu * @Date 2024/2/19 */ public class ExportExcelByTemplateUtils { /** * @description: 根據(jù)模版導(dǎo)出Excel入口(單個list數(shù)據(jù)) * @param templateFileName * @param exportFilePathAndName * @param staticDataMap * @param dataId * @param originDataList * @return void * @author susu * @date 2024/2/21 */ public static void doExportExcelOneListByTemplate(String templateFileName, String exportFilePathAndName, Map<String, Object> staticDataMap, String dataId, List<?> originDataList) throws Exception{ List<Map<String, Object>> exportDataList = MapObjectUtil.objListToMapList(originDataList); // 只有一個list數(shù)據(jù) List<DynamicDataMapping> dynamicDataMappingList = DynamicDataMapping.createOneDataList(dataId, exportDataList); // 導(dǎo)出 ExcelTemplateProc.doExportExcelByTemplateProc(templateFileName,exportFilePathAndName,staticDataMap,dynamicDataMappingList); } /** * @description: 根據(jù)模版導(dǎo)出Excel入口(多個list數(shù)據(jù)) * @param templateFileName * @param exportFilePathAndName * @param staticSource * @param originDataMapList * @return void * @author susu * @date 2024/2/20 */ public static void doExportExcelMoreListByTemplate(String templateFileName, String exportFilePathAndName, Map<String, Object> staticSource, Map<String, List<?>> originDataMapList) throws Exception{ Map<String,List<Map<String, Object>>> transMap = new HashMap<>(); originDataMapList.forEach((dataId,originDataList)->{ List<Map<String, Object>> transDataList = MapObjectUtil.objListToMapList(originDataList); transMap.put(dataId,transDataList); }); // 多個list類型數(shù)據(jù) List<DynamicDataMapping> dynamicDataMappingList = DynamicDataMapping.createMorDataList(transMap); // 導(dǎo)出 ExcelTemplateProc.doExportExcelByTemplateProc(templateFileName,exportFilePathAndName,staticSource,dynamicDataMappingList); } }
4. 附項目
4.1 一般導(dǎo)出項目代碼
- 如下:
Java導(dǎo)出excel工具詳細介紹(POI 和 EasyExcel),各種復(fù)雜需求情況的導(dǎo)出(包括動態(tài)設(shè)置合并單元格等).
4.2 根據(jù)模版導(dǎo)出項目代碼
- 如下:
Java根據(jù)自定義模版導(dǎo)出各種需求的Excel(使用POI).
文章來源地址http://www.zghlxwxcb.cn/news/detail-861808.html
文章來源:http://www.zghlxwxcb.cn/news/detail-861808.html
到了這里,關(guān)于Java根據(jù)excel模版導(dǎo)出Excel(easyexcel、poi)——含項目測試?yán)幽脕砑从玫奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!