package com.zzg.common.utils; import cn.afterturn.easypoi.cache.manager.POICacheManager; import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.ExcelImportUtil; import cn.afterturn.easypoi.excel.ExcelXorHtmlUtil; import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams; import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.ImportParams; import cn.afterturn.easypoi.excel.entity.TemplateExportParams; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult; import cn.afterturn.easypoi.util.PoiMergeCellUtil; import cn.afterturn.easypoi.word.WordExportUtil; import cn.afterturn.easypoi.word.parse.ParseWord07; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; /** * Excel导入导出工具类 */ public class ExcelUtils { /** * excel 导出 * * @param list 数据列表 * @param fileName 导出时的excel名称 * @param response */ public static void exportExcel(List> list, String fileName, HttpServletResponse response) throws IOException { defaultExport(list, fileName, response); } /** * 默认的 excel 导出 * * @param list 数据列表 * @param fileName 导出时的excel名称 * @param response */ private static void defaultExport(List> list, String fileName, HttpServletResponse response) throws IOException { //把数据添加到excel表格中 Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF); downLoadExcel(fileName, response, workbook); } /** * excel 导出 * * @param list 数据列表 * @param pojoClass pojo类型 * @param fileName 导出时的excel名称 * @param response * @param exportParams 导出参数(标题、sheet名称、是否创建表头,表格类型) */ private static void defaultExport(List list, Class pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) throws IOException { //把数据添加到excel表格中 Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list); downLoadExcel(fileName, response, workbook); } /** * @Description: 合并指定列单元格并导出(合并行) * @Date: 2021/5/24 9:42 * @Param templatePath: 模板路径 * @Param map: 需要导出的数据map * @Param fileName: 导出文件名称 * @Param response: response * @Param sheetMergeParamList: sheet参数集合 * @return: void * @Version: 1.0 **/ public static void exportMergeExcel(TemplateExportParams templatePath, Map map, String fileName, HttpServletResponse response, List sheetMergeParamList) throws IOException { Workbook workbook = ExcelExportUtil.exportExcel(templatePath, map); //合并单元格 mergeExcel(workbook, sheetMergeParamList); downLoadExcel(fileName, response, workbook); } /** * @Description: 合并单元格具体执行方法 * @Date: 2021/5/24 14:58 * @Param workbook: 工作薄 * @Param sheetMergeParamList: sheet集合 * @return: void * @Version: 1.0 **/ private static void mergeExcel(Workbook workbook, List sheetMergeParamList) { for (SheetMergeParam sheetMergeParam : sheetMergeParamList) { Sheet sheet = workbook.getSheetAt(sheetMergeParam.getSheetIndex()); int lastRowNum = sheet.getLastRowNum(); int i; for (i = 0; i < lastRowNum; i++) { //获取每行第一个单元格 if (null == sheet.getRow(i) || null == sheet.getRow(i).getCell(0)) { continue; } Cell cell = sheet.getRow(i).getCell(0); if (sheetMergeParam.getIgnoreCellValues().contains(cell.getStringCellValue()) || StringUtils.isEmpty(cell.getStringCellValue())) { continue; } //定义合并终止行数 int endRowNum = 0; for (int j = i + 1; j < lastRowNum; j++) { Cell desColumn = sheet.getRow(i).getCell(sheetMergeParam.getDesColumnIndex()); Cell nextDesColumn = sheet.getRow(j).getCell(sheetMergeParam.getDesColumnIndex()); if (!desColumn.getStringCellValue().equals(nextDesColumn.getStringCellValue())) { //值不同,终止此层循环 break; } endRowNum++; } //判断是否有合并项 if (endRowNum == 0) { continue; } //合并单元格操作 for (int z = 0; z < sheetMergeParam.getMergeColumnIndexs().length; z++) { //合并起始行,终止行,起始列,终止列 int firstRow = i; int lastRow = i + endRowNum; int firstCol = sheetMergeParam.getMergeColumnIndexs()[z]; int lastCol = sheetMergeParam.getMergeColumnIndexs()[z]; PoiMergeCellUtil.addMergedRegion(sheet, firstRow, lastRow, firstCol, lastCol); } //合并后行号下移 i = i + endRowNum; } } } /** * excel 导出 * * @param list 数据列表 * @param pojoClass pojo类型 * @param fileName 导出时的excel名称 * @param exportParams 导出参数(标题、sheet名称、是否创建表头,表格类型) * @param response */ public static void exportExcel(List list, Class pojoClass, String fileName, ExportParams exportParams, HttpServletResponse response) throws IOException { defaultExport(list, pojoClass, fileName, response, exportParams); } /** * excel 导出 * * @param list 数据列表 * @param title 表格内数据标题 * @param sheetName sheet名称 * @param pojoClass pojo类型 * @param fileName 导出时的excel名称 * @param response */ public static void exportExcel(List list, String title, String sheetName, Class pojoClass, String fileName, HttpServletResponse response) throws IOException { defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName, ExcelType.XSSF)); } /** * 根据模板生成excel后导出 * * @param templatePath 模板路径 * @param map 数据集合 * @param fileName 文件名 * @param response * @throws IOException */ public static void exportExcel(TemplateExportParams templatePath, Map map, String fileName, HttpServletResponse response) throws IOException { Workbook workbook = ExcelExportUtil.exportExcel(templatePath, map); downLoadExcel(fileName, response, workbook); } /** * excel 导出 * * @param list 数据列表 * @param title 表格内数据标题 * @param sheetName sheet名称 * @param pojoClass pojo类型 * @param fileName 导出时的excel名称 * @param isCreateHeader 是否创建表头 * @param response */ public static void exportExcel(List list, String title, String sheetName, Class pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) throws IOException { ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.XSSF); exportParams.setCreateHeadRows(isCreateHeader); defaultExport(list, pojoClass, fileName, response, exportParams); } /** * excel下载 * * @param fileName 下载时的文件名称 * @param response * @param workbook excel数据 */ private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException { try { 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 (Exception e) { throw new IOException(e.getMessage()); } } /** * word下载 * * @param fileName 下载时的文件名称 * @param response * @param doc */ private static void downLoadWord(String fileName, HttpServletResponse response, XWPFDocument doc) throws IOException { try { response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/msword"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".docx", "UTF-8")); doc.write(response.getOutputStream()); } catch (Exception e) { throw new IOException(e.getMessage()); } } /** * excel 导入 * * @param file excel文件 * @param pojoClass pojo类型 * @param * @return */ public static List importExcel(MultipartFile file, Class pojoClass) throws IOException { return importExcel(file, 1, 1, pojoClass); } /** * excel 导入 * * @param filePath excel文件路径 * @param titleRows 表格内数据标题行 * @param headerRows 表头行 * @param pojoClass pojo类型 * @param * @return */ public static List importExcel(String filePath, Integer titleRows, Integer headerRows, Class pojoClass) throws IOException { if (StringUtils.isBlank(filePath)) { return null; } ImportParams params = new ImportParams(); params.setTitleRows(titleRows); params.setHeadRows(headerRows); params.setNeedSave(true); params.setSaveUrl("/excel/"); try { return ExcelImportUtil.importExcel(new File(filePath), pojoClass, params); } catch (NoSuchElementException e) { throw new IOException("模板不能为空"); } catch (Exception e) { throw new IOException(e.getMessage()); } } /** * excel 导入 * * @param file 上传的文件 * @param titleRows 表格内数据标题行 索引从1开始 * @param headerRows 表头行 索引从1开始 * @param pojoClass pojo类型 * @param * @return */ public static List importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class pojoClass) throws IOException { if (file == null) { return null; } try { return importExcel(file.getInputStream(), titleRows, headerRows, pojoClass); } catch (Exception e) { throw new IOException(e.getMessage()); } } /** * excel 导入 * * @param inputStream 文件输入流 * @param titleRows 表格内数据标题行 * @param headerRows 表头行 * @param pojoClass pojo类型 * @param * @return */ public static List importExcel(InputStream inputStream, Integer titleRows, Integer headerRows, Class pojoClass) throws IOException { if (inputStream == null) { return null; } ImportParams params = new ImportParams(); params.setTitleRows(titleRows); params.setHeadRows(headerRows); params.setSaveUrl("/excel/"); params.setNeedSave(true); try { return ExcelImportUtil.importExcel(inputStream, pojoClass, params); } catch (NoSuchElementException e) { throw new IOException("excel文件不能为空"); } catch (Exception e) { throw new IOException(e.getMessage()); } } /** * excel转html预览 * * @param filePath 文件路径 * @param response * @throws Exception */ public static void excelToHtml(String filePath, HttpServletResponse response) throws Exception { ExcelToHtmlParams params = new ExcelToHtmlParams(WorkbookFactory.create(POICacheManager.getFile(filePath)), true); response.getOutputStream().write(ExcelXorHtmlUtil.excelToHtml(params).getBytes()); } /** * word模板导出 * * @param map * @param templatePath * @param fileName * @param response * @throws Exception */ public static void WordTemplateExport(Map map, String templatePath, String fileName, HttpServletResponse response) throws Exception { XWPFDocument doc = WordExportUtil.exportWord07(templatePath, map); downLoadWord(fileName, response, doc); } /** * word模板导出多页 * * @param list * @param templatePath * @param fileName * @param response * @throws Exception */ public static void WordTemplateExportMorePage(List> list, String templatePath, String fileName, HttpServletResponse response) throws Exception { XWPFDocument doc = new ParseWord07().parseWord(templatePath, list); downLoadWord(fileName, response, doc); } /** * excel 导入,有错误信息 * * @param file 上传的文件 * @param pojoClass pojo类型 * @param * @return */ public static ExcelImportResult importExcelMore(MultipartFile file, Class pojoClass) throws IOException { if (file == null) { return null; } try { return importExcelMore(file.getInputStream(), pojoClass); } catch (Exception e) { throw new IOException(e.getMessage()); } } /** * excel 导入 * * @param inputStream 文件输入流 * @param pojoClass pojo类型 * @param * @return */ private static ExcelImportResult importExcelMore(InputStream inputStream, Class pojoClass) throws IOException { if (inputStream == null) { return null; } ImportParams params = new ImportParams(); params.setTitleRows(1);//表格内数据标题行 params.setHeadRows(1);//表头行 params.setSaveUrl("/excel/"); params.setNeedSave(true); params.setNeedVerify(true); try { return ExcelImportUtil.importExcelMore(inputStream, pojoClass, params); } catch (NoSuchElementException e) { throw new IOException("excel文件不能为空"); } catch (Exception e) { throw new IOException(e.getMessage()); } } /** * @param response * @param fileName * @param inStream * @throws UnsupportedEncodingException */ public static void exportByLocal(HttpServletResponse response, String fileName, InputStream inStream) throws UnsupportedEncodingException { String fileNameURL = URLEncoder.encode(fileName, "UTF-8"); // response.setHeader("Content-disposition", "attachment;filename=" + fileNameURL + ";" + "filename*=utf-8''" + fileNameURL); response.setHeader("Content-disposition", "attachment;" + "filename*=" + fileNameURL); if (fileName.endsWith("xls")) { response.setContentType("application/vnd.ms-excel"); } else if (fileName.endsWith("xlsx")) { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); } // 循环取出流中的数据 byte[] b = new byte[100]; int len; try { while ((len = inStream.read(b)) > 0) response.getOutputStream().write(b, 0, len); inStream.close(); } catch (IOException e) { e.printStackTrace(); } } /** * @param response * @param path * @return * @throws IOException */ public static HttpServletResponse exportByInstream(HttpServletResponse response, String path) throws IOException { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = file.getName(); // 取得文件的后缀名。 String ext = filename.substring(filename.lastIndexOf(".") + 1); // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(path)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); // 设置response的Header response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes())); response.addHeader("Content-Length", "" + file.length()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); if (ext.equals("xls")) { response.setContentType("application/vnd.ms-excel"); } else if (ext.equals("xlsx")) { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); } toClient.write(buffer); toClient.flush(); toClient.close(); return response; } /** * 在EXCEL(含表头)模板中插入数据 * @param sheetName 表名 * @param body 主体数据 * @param response response * @param file 模板文件 * @param startRow 从第几行开始,excel第一行下标为0 */ public static void insertBodyData(String sheetName, List> body, HttpServletResponse response, String file, int startRow) throws IOException { File file1 = new File(file); if (!file1.exists()){ throw new IOException("模板文件不存在"); } /*FileInputStream fileS = new FileInputStream(file); POIFSFileSystem poifsFileSystem = new POIFSFileSystem(fileS); // HSSFWorkbook wb = new HSSFWorkbook(poifsFileSystem); XSSFWorkbook wb = new XSSFWorkbook(fileS); XSSFSheet hssfSheet = wb.getSheet(sheetName); XSSFCellStyle cellStyle= wb.createCellStyle(); cellStyle.setBorderTop(BorderStyle.THIN);//上边框-单线 cellStyle.setBorderBottom(BorderStyle.THIN);//下边框-双线 cellStyle.setBorderLeft(BorderStyle.THIN);//左边框-无边框 cellStyle.setBorderRight(BorderStyle.THIN);//右边框-虚线 cellStyle.setAlignment(HorizontalAlignment.CENTER);*/ FileInputStream inputStream = new FileInputStream(file); Workbook workbook = null; if(file.endsWith(".xls")) { workbook = new HSSFWorkbook(inputStream); // 2003版Excel } else if (file.endsWith(".xlsx")) { workbook = new XSSFWorkbook(inputStream); // 2007版Excel } else { throw new IllegalArgumentException("Invalid Excel file format"); } CellStyle cellStyle= workbook.createCellStyle(); cellStyle.setBorderTop(BorderStyle.THIN);//上边框-单线 cellStyle.setBorderBottom(BorderStyle.THIN);//下边框-双线 cellStyle.setBorderLeft(BorderStyle.THIN);//左边框-无边框 cellStyle.setBorderRight(BorderStyle.THIN);//右边框-虚线 cellStyle.setAlignment(HorizontalAlignment.CENTER); Sheet hssfSheet = workbook.getSheetAt(0); // 设置主体数据 for (int rowNum = 0; rowNum < body.size(); rowNum++) { int rowIndex = rowNum + startRow; // 往excel表格创建一行,excel的行号是从0开始的 Row hssfRow = hssfSheet.createRow(rowIndex); List data = body.get(rowNum); for (int columnNum = 0; columnNum < data.size(); columnNum++) { // 创建单元格 Cell hssfCell = hssfRow.createCell(columnNum); hssfCell.setCellStyle(cellStyle); // 设置单元格的值 hssfCell.setCellValue(data.size() < columnNum ? "-" : data.get(columnNum)); } } try { // response.setContentType("application/octet-stream"); // response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(sheetName, "UTF-8")); response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(sheetName + ".xlsx", "UTF-8")); workbook.write(response.getOutputStream()); } catch (IOException e) { e.printStackTrace(); }finally { try { // poifsFileSystem.close(); inputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }