001package top.cenze.utils; 002 003import cn.hutool.core.io.FileUtil; 004import cn.hutool.core.util.ObjectUtil; 005import com.spire.xls.Workbook; 006import com.spire.xls.Worksheet; 007import com.spire.xls.core.spreadsheet.HTMLOptions; 008import lombok.SneakyThrows; 009import lombok.extern.slf4j.Slf4j; 010import org.springframework.web.multipart.MultipartFile; 011import top.cenze.utils.file.CZFileUtil; 012import top.cenze.utils.file.MultipartFileUtil; 013 014import java.io.File; 015 016/** 017 * @desc: excel转换工具 018 * https://huaweicloud.csdn.net/63875467dacf622b8df8ae8a.html 019 * https://repo.e-iceblue.cn/#browse/browse:maven-public:e-iceblue%2Fspire.xls.free%2F2.2.0%2Fspire.xls.free-2.2.0.jar 020 * https://blog.csdn.net/zhuocailing3390/article/details/122527100 021 * https://gitee.com/lookWord/itext7-demo/tree/master/src/main/java/com/tk/itext7demo/utils/excel 022 * https://blog.51cto.com/u_16175446/7287269 023 * @author: chengze 024 * @createByDate: 2024/1/5 9:19 025 */ 026@Slf4j 027public class ExcelConvertUtil { 028 /** 029 * 转PDF(第一个sheet,全部填充至一页内,且列宽根据内容自动调整) 030 * @param excelFile excel 文件 031 * @return 032 */ 033 public static MultipartFile toPdf(MultipartFile excelFile) { 034 return toPdf(excelFile, 0, true, true); 035 } 036 037 /** 038 * 转PDF(第一个sheet,全部填充至一页内,且列宽根据内容自动调整) 039 * @param excelFile excel 文件 040 * @param fitToPage 整个sheet是否都填充到一页PDF内(一页显示所有sheet内容) 041 * @return 042 */ 043 public static MultipartFile toPdf(MultipartFile excelFile, Boolean fitToPage) { 044 return toPdf(excelFile, 0, fitToPage, true); 045 } 046 047 /** 048 * 转PDF 049 * @param excelFile excel 文件 050 * @param sheetNum 第几个sheet(sheet索引,第一个从0开始) 051 * @param fitToPage 整个sheet是否都填充到一页PDF内(一页显示所有sheet内容) 052 * @param autoFitColumn sheet列中的字符超过列宽,是否自动调整列宽 053 * @return 054 */ 055 @SneakyThrows 056 public static MultipartFile toPdf(MultipartFile excelFile, Integer sheetNum, Boolean fitToPage, Boolean autoFitColumn) { 057 File inFile = CZFileUtil.loadFile(excelFile); 058 log.info("toPdf in file name: {}, length: {}, path: {}", inFile.getName(), inFile.length(), inFile.getPath()); 059 if (ObjectUtil.isNull(inFile)) { 060 return null; 061 } 062 063 MultipartFile tmpFile = null; 064 File outFile = CZFileUtil.createPdfFile(); 065 log.info("toPdf out file1 name: {}, length: {}, path: {}", outFile.getName(), outFile.length(), outFile.getPath()); 066 toPdf(inFile.getPath(), outFile.getPath(), sheetNum, fitToPage, autoFitColumn); 067 outFile = CZFileUtil.loadFile(outFile.getPath()); 068 log.info("toPdf out file2 name: {}, length: {}, path: {}", outFile.getName(), outFile.length(), outFile.getPath()); 069 if (ObjectUtil.isNotNull(outFile) && FileUtil.exist(outFile)) { 070 tmpFile = MultipartFileUtil.getMultipartFile(outFile); 071 } 072 073 FileUtil.del(inFile); 074 FileUtil.del(outFile); 075 076 log.info("toPdf multi file name: {}, size: {}", tmpFile.getOriginalFilename(), tmpFile.getSize()); 077 078 return tmpFile; 079 } 080 081 /** 082 * 转PDF 083 * @param inputFilePath excel文件路径 084 * @param outputFilePath 输出pdf文件路径 085 * @param sheetNum 第几个sheet(sheet索引,第一个从0开始) 086 * @param fitToPage 整个sheet是否都填充到一页PDF内(一页显示所有sheet内容) 087 * @param autoFitColumn sheet列中的字符超过列宽,是否自动调整列宽 088 */ 089 public static void toPdf(String inputFilePath, String outputFilePath, Integer sheetNum, Boolean fitToPage, Boolean autoFitColumn) { 090 if (ObjectUtil.isNull(sheetNum)) { 091 sheetNum = 0; 092 } 093 094 Workbook wb = new Workbook(); 095 // 引入Excel文件 096 wb.loadFromFile(inputFilePath); 097 Worksheet sheet = wb.getWorksheets().get(sheetNum); 098 // 所有内容都填充到一页中 099 if (ObjectUtil.isNotNull(fitToPage) && fitToPage) { 100 wb.getConverterSetting().setSheetFitToPage(true); 101 } 102 // 列宽自动调整 103 if (ObjectUtil.isNotNull(autoFitColumn) && autoFitColumn) { 104 for (int i = 1; i < sheet.getColumns().length; i++) 105 { 106 sheet.autoFitColumn(i); 107 } 108 } 109 110 sheet.saveToPdf(outputFilePath); 111 } 112 113 /** 114 * 转PNG(第一个sheet,全部填充至一页内,且列宽根据内容自动调整) 115 * @param excelFile 116 * @return 117 */ 118 public static MultipartFile toPng(MultipartFile excelFile) { 119 return toPng(excelFile, 0, true, true); 120 } 121 122 /** 123 * 转PNG 124 * @param excelFile excel 文件 125 * @param sheetNum 第几个sheet(sheet索引,第一个从0开始) 126 * @param fitToPage 整个sheet是否都填充到一页PNG内(一页显示所有sheet内容) 127 * @param autoFitColumn sheet列中的字符超过列宽,是否自动调整列宽 128 * @return 129 */ 130 @SneakyThrows 131 public static MultipartFile toPng(MultipartFile excelFile, Integer sheetNum, Boolean fitToPage, Boolean autoFitColumn) { 132 File inFile = CZFileUtil.loadFile(excelFile); 133 if (ObjectUtil.isNull(inFile)) { 134 return null; 135 } 136 137 MultipartFile tmpFile = null; 138 File outFile = CZFileUtil.createPngFile(); 139 toPng(inFile.getPath(), outFile.getPath(), sheetNum, fitToPage, autoFitColumn); 140 outFile = CZFileUtil.loadFile(outFile.getPath()); 141 if (ObjectUtil.isNotNull(outFile) && FileUtil.exist(outFile)) { 142 tmpFile = MultipartFileUtil.getMultipartFile(outFile); 143 } 144 145 FileUtil.del(inFile); 146 FileUtil.del(outFile); 147 148 return tmpFile; 149 } 150 151 /** 152 * 转PNG 153 * @param inputFilePath excel文件路径 154 * @param outputFilePath 输出png文件路径 155 * @param sheetNum 第几个sheet(sheet索引,第一个从0开始) 156 * @param fitToPage 整个sheet是否都填充到一页Png内(一页显示所有sheet内容) 157 * @param autoFitColumn sheet列中的字符超过列宽,是否自动调整列宽 158 */ 159 public static void toPng(String inputFilePath, String outputFilePath, Integer sheetNum, Boolean fitToPage, Boolean autoFitColumn) { 160 if (ObjectUtil.isNull(sheetNum)) { 161 sheetNum = 0; 162 } 163 164 Workbook wb = new Workbook(); 165 // 引入Excel文件 166 wb.loadFromFile(inputFilePath); 167 Worksheet sheet = wb.getWorksheets().get(sheetNum); 168 // 所有内容都填充到一页中 169 if (ObjectUtil.isNotNull(fitToPage) && fitToPage) { 170 wb.getConverterSetting().setSheetFitToPage(true); 171 } 172 // 列宽自动调整 173 if (ObjectUtil.isNotNull(autoFitColumn) && autoFitColumn) { 174 for (int i = 1; i < sheet.getColumns().length; i++) 175 { 176 sheet.autoFitColumn(i); 177 } 178 } 179 180 sheet.saveToImage(outputFilePath); 181 } 182 183 /** 184 * 转HTML(第一个sheet,全部填充至一页内,且列宽根据内容自动调整) 185 * @param excelFile 186 * @return 187 */ 188 public static MultipartFile toHtml(MultipartFile excelFile) { 189 return toHtml(excelFile, 0, true, true); 190 } 191 192 /** 193 * 转HTML 194 * @param excelFile excel 文件 195 * @param sheetNum 第几个sheet(sheet索引,第一个从0开始) 196 * @param fitToPage 整个sheet是否都填充到一页html内(一页显示所有sheet内容) 197 * @param autoFitColumn sheet列中的字符超过列宽,是否自动调整列宽 198 * @return 199 */ 200 @SneakyThrows 201 public static MultipartFile toHtml(MultipartFile excelFile, Integer sheetNum, Boolean fitToPage, Boolean autoFitColumn) { 202 File inFile = CZFileUtil.loadFile(excelFile); 203 if (ObjectUtil.isNull(inFile)) { 204 return null; 205 } 206 207 MultipartFile tmpFile = null; 208 File outFile = CZFileUtil.createHtmlFile(); 209 toHtml(inFile.getPath(), outFile.getPath(), sheetNum, fitToPage, autoFitColumn); 210 outFile = CZFileUtil.loadFile(outFile.getPath()); 211 if (ObjectUtil.isNotNull(outFile) && FileUtil.exist(outFile)) { 212 tmpFile = MultipartFileUtil.getMultipartFile(outFile); 213 } 214 215// FileUtil.del(inFile); 216// FileUtil.del(outFile); 217 218 return tmpFile; 219 } 220 221 /** 222 * 转HTML 223 * @param inputFilePath excel文件路径 224 * @param outputFilePath 输出html文件路径 225 * @param sheetNum 第几个sheet(sheet索引,第一个从0开始) 226 * @param fitToPage 整个sheet是否都填充到一页html内(一页显示所有sheet内容) 227 * @param autoFitColumn sheet列中的字符超过列宽,是否自动调整列宽 228 */ 229 public static void toHtml(String inputFilePath, String outputFilePath, Integer sheetNum, Boolean fitToPage, Boolean autoFitColumn) { 230 if (ObjectUtil.isNull(sheetNum)) { 231 sheetNum = 0; 232 } 233 234 Workbook wb = new Workbook(); 235 // 引入Excel文件 236 wb.loadFromFile(inputFilePath); 237 Worksheet sheet = wb.getWorksheets().get(sheetNum); 238 // 所有内容都填充到一页中 239 if (ObjectUtil.isNotNull(fitToPage) && fitToPage) { 240 wb.getConverterSetting().setSheetFitToPage(true); 241 } 242 // 列宽自动调整 243 if (ObjectUtil.isNotNull(autoFitColumn) && autoFitColumn) { 244 for (int i = 1; i < sheet.getColumns().length; i++) 245 { 246 sheet.autoFitColumn(i); 247 } 248 } 249 250 //Set embedded image as true 251 HTMLOptions options = new HTMLOptions(); 252 options.setImageEmbedded(true); 253 254 sheet.saveToHtml(outputFilePath, options); 255 } 256 257 @SneakyThrows 258 public static void office2PDF(String inputFilePath, String outputFilePath) { 259// // 测试word文档转pdf 260//// 创建输入流 261// FileInputStream input = new FileInputStream(inputFilePath); 262//// 创建输出流 263// FileOutputStream output = new FileOutputStream(outputFilePath); 264// 265// 266// LocalOfficeManager.Builder builder = LocalOfficeManager.builder(); 267//// 设置本地Office地址,推荐LibreOffice 268// builder.officeHome("C:/Program Files/LibreOffice"); 269//// 部署主机,本地启动 270// builder.hostName("127.0.0.1"); 271//// 部署端口,可以设置多个 272// builder.portNumbers(9000, 9001, 9002); 273//// 单任务过期时间 默认:120000 2分钟 274// builder.taskExecutionTimeout((long) (2 * 1000 * 60)); 275//// 任务过期时间 默认:30000 3 秒 276// builder.taskQueueTimeout((long) (1000 * 60 * 60)); 277//// 可以执行的最大任务数,默认200 278// builder.maxTasksPerProcess(100); 279//// 构建 280// LocalOfficeManager manager = builder.build(); 281//// 启动 282// manager.start(); 283// 284// log.info("office2PDF start"); 285// LocalConverter converter = LocalConverter.builder().officeManager(manager).build(); 286// // 进行格式转换 287// converter.convert(input).as(DefaultDocumentFormatRegistry.XLSX) 288// .to(output).as(DefaultDocumentFormatRegistry.PDF).execute(); 289// log.info("office2PDF end"); 290// 291// // 关闭流 292// output.close(); 293// input.close(); 294// manager.stop(); 295// DefaultExecutor exec = new DefaultExecutor(); 296// File tempFolder = new File(outputFilePath); 297// // 同步等待 298// Semaphore semaphore = new Semaphore(1); 299// semaphore.acquire(); 300// ExecuteResultHandler erh = new ExecuteResultHandler() { 301// @Override 302// public void onProcessComplete(int i) { 303// semaphore.release(); 304// //转换完成逻辑 305// } 306// 307// @Override 308// public void onProcessFailed(ExecuteException e) { 309// semaphore.release(); 310// //转换失败逻辑 311// e.printStackTrace(); 312// } 313// }; 314// String command = "soffice --invisible --convert-to pdf --outdir \"" + tempFolder.getAbsolutePath() + "\" \"" + officeFile.getAbsolutePath() + "\""; 315// System.out.println("执行office文件转换任务,命令为" + command); 316// exec.execute(CommandLine.parse(command), erh); 317// // 等待执行完成 318// semaphore.acquire(); 319// File file = new File(tempFolder.getAbsolutePath() + File.separator + officeFile.getName().substring(0, officeFile.getName().indexOf(".")) + ".pdf"); 320// if (!file.exists()) { 321// // 转换失败逻辑 322// } 323// return file; 324 } 325}