LICENSE
File was deleted archiveManager/pom.xml
@@ -22,7 +22,27 @@ <groupId>com.ruoyi</groupId> <artifactId>ruoyi-common</artifactId> </dependency> <!-- <dependency>--> <!-- <groupId>com.aspose</groupId>--> <!-- <artifactId>aspose-cells</artifactId>--> <!-- <version>23.9</version>--> <!-- </dependency>--> <!-- Aspose.Words(Word 转 PDF) --> <!-- <dependency>--> <!-- <groupId>com.aspose</groupId>--> <!-- <artifactId>aspose-words</artifactId>--> <!-- <version>18.9</version>--> <!-- </dependency>--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.1</version> archiveManager/src/main/java/com/ruoyi/domain/vo/DocumentMaterialsVoSmall.java
@@ -11,25 +11,25 @@ public class DocumentMaterialsVoSmall { @Excel(name="序号",width = 5, headerColor = IndexedColors.BLACK, headerFontBold = true) @Excel(name="序号",width = 5, headerFontSize=12, headerColor = IndexedColors.BLACK, headerFontBold = true) private Long num; @Excel(name = "文件编号",width = 10, headerColor = IndexedColors.BLACK, headerFontBold = true) @Excel(name = "文件编号",width = 10, headerFontSize=12,headerColor = IndexedColors.BLACK, headerFontBold = true) private String documentNumber; @Excel(name = "责任者",width = 10, headerColor = IndexedColors.BLACK, headerFontBold = true) @Excel(name = "责任者",width = 10, headerFontSize=12,headerColor = IndexedColors.BLACK, headerFontBold = true) private String creator; @Excel(name = "文件题名",width = 36, headerColor = IndexedColors.BLACK, headerFontBold = true) @Excel(name = "文件题名",width = 30, headerFontSize=12,headerColor = IndexedColors.BLACK, headerFontBold = true) private String title; @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "日期", width = 12, dateFormat = "yyyy-MM-dd", headerColor = IndexedColors.BLACK, headerFontBold = true) @Excel(name = "日期", width = 10, headerFontSize=12,dateFormat = "yyyy-MM-dd", headerColor = IndexedColors.BLACK, headerFontBold = true) private Date date; @Excel(name = "页号",width = 10, headerColor = IndexedColors.BLACK, headerFontBold = true) @Excel(name = "页号",width = 10, headerFontSize=12, headerColor = IndexedColors.BLACK, headerFontBold = true) private Long pageNumber; @Excel(name = "备注",width = 10, headerColor = IndexedColors.BLACK, headerFontBold = true) @Excel(name = "备注",width = 8, headerFontSize=12,headerColor = IndexedColors.BLACK, headerFontBold = true) private String remarks; public DocumentMaterialsVoSmall(Long num, String documentNumber, String creator, String title, Date date, Long pageNumber, String remarks) { archiveManager/src/main/java/com/ruoyi/service/impl/BarcodeService.java
@@ -16,7 +16,7 @@ Code128Bean barcodeGenerator = new Code128Bean(); final int dpi = 160; barcodeGenerator.setModuleWidth(0.21); barcodeGenerator.setBarHeight(4.0); // 设置条形码高度为64 barcodeGenerator.setBarHeight(8.0); // 设置条形码高度为64 barcodeGenerator.doQuietZone(false); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); archiveManager/src/main/java/com/ruoyi/service/impl/pdfGenerateService.java
@@ -267,62 +267,76 @@ } // 自定义页面事件类,用于在每个新页面添加卷内封面内容 // 自定义页面事件类,用于在每个新页面添加卷内封面和卷号 private class DirectoryHeaderPageEvent extends PdfPageEventHelper { private String volumeNumber; private byte[] barcodeImageBytes; private BaseFont bfChinese; private Font chineseFont; private Font chineseFont1; private Image barcodeImage; public DirectoryHeaderPageEvent(String volumeNumber, byte[] barcodeImageBytes) { public DirectoryHeaderPageEvent(String volumeNumber, BaseFont bfChinese, Font chineseFont, Font chineseFont1, Image barcodeImage) { this.volumeNumber = volumeNumber; this.barcodeImageBytes = barcodeImageBytes; this.bfChinese = bfChinese; this.chineseFont = chineseFont; this.chineseFont1 = chineseFont1; this.barcodeImage = barcodeImage; } @Override public void onStartPage(PdfWriter writer, Document document) { try { // 设置中文字体 BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font chineseFont = new Font(bfChinese, 12); Font chineseFont1 = new Font(bfChinese, 16, Font.BOLD); PdfContentByte cb = writer.getDirectContent(); float pageWidth = document.getPageSize().getWidth(); float pageHeight = document.getPageSize().getHeight(); // 添加条形码 Image img = Image.getInstance(barcodeImageBytes); PdfPCell pdfPCell = new PdfPCell(img); pdfPCell.setBorder(Rectangle.NO_BORDER); pdfPCell.setMinimumHeight(40); pdfPCell.setUseAscender(true); pdfPCell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT); pdfPCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); pdfPCell.setColspan(2); pdfPCell.setPaddingBottom(30); // 1. 添加条形码(居中显示,页面顶部) float barcodeWidth = barcodeImage.getScaledWidth(); float barcodeHeight = barcodeImage.getScaledHeight(); float barcodeX = (pageWidth - barcodeWidth) / 2; float barcodeY = pageHeight - 50 - barcodeHeight; // 页面顶部下方50点 barcodeImage.setAbsolutePosition(barcodeX, barcodeY); cb.addImage(barcodeImage); float[] columnWidths1 = {35f, 65f}; PdfPTable table1 = new PdfPTable(columnWidths1); table1.setWidthPercentage(80); table1.setHorizontalAlignment(Element.ALIGN_LEFT); table1.setSpacingBefore(30f); table1.addCell(pdfPCell); // 2. 添加卷内目录标题(居中显示,条形码下方) String title = "卷 内 目 录"; float titleX = pageWidth / 2; float titleY = pageHeight - 100; // 页面顶部下方100点 cb.beginText(); // 创建并设置标题为加粗字体 Font boldTitleFont = new Font(bfChinese, 16, Font.BOLD); cb.setFontAndSize(boldTitleFont.getBaseFont(), boldTitleFont.getSize()); cb.setColorFill(BaseColor.BLACK); cb.showTextAligned(PdfContentByte.ALIGN_CENTER, title, titleX, titleY, 0); cb.endText(); PdfContentByte canvas = writer.getDirectContent(); ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(" ", chineseFont), document.left(), document.top() - 50, 0); document.add(table1); // 3. 添加卷号(居右显示,标题下方) String label = "卷号:"; String value = volumeNumber; float recordInfoX = pageWidth - 30; float recordInfoY = pageHeight - 130; // 页面顶部下方130点 // 添加标题 Paragraph title = new Paragraph("卷 内 目 录", chineseFont1); title.setAlignment(Element.ALIGN_CENTER); document.add(title); Paragraph withNewLine = new Paragraph("\n"); document.add(withNewLine); document.add(withNewLine); // 先绘制标签"卷号:" cb.beginText(); // 设置加粗字体,通过Font.BOLD参数 Font boldFont = new Font(bfChinese, 16, Font.BOLD); cb.setFontAndSize(boldFont.getBaseFont(), boldFont.getSize()); cb.setColorFill(BaseColor.BLACK); cb.showTextAligned(PdfContentByte.ALIGN_RIGHT, label + value, recordInfoX, recordInfoY, 0); cb.endText(); // 添加卷号 Paragraph recordInfo = new Paragraph("卷号:" + volumeNumber, chineseFont); recordInfo.setAlignment(Element.ALIGN_RIGHT); document.add(recordInfo); // 计算值的位置并绘制下划线 float labelWidth = bfChinese.getWidthPoint(label, 12); float valueWidth = bfChinese.getWidthPoint(value, 12); float underlineStartX = recordInfoX - valueWidth; float underlineEndX = recordInfoX; float underlineY = recordInfoY - 2; document.add(withNewLine); document.add(withNewLine); cb.setColorStroke(BaseColor.BLACK); cb.setLineWidth(0.5f); cb.moveTo(underlineStartX, underlineY); cb.lineTo(underlineEndX, underlineY); cb.stroke(); } catch (Exception e) { e.printStackTrace(); @@ -335,27 +349,44 @@ Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdfPath)); // 添加页面事件,在每个新页面自动添加卷内封面内容 String volumeNumber = dvss.get(0).getRecordId(); byte[] barcodeImageBytes = barcodeService.generateBarcodeImage(volumeNumber); writer.setPageEvent(new DirectoryHeaderPageEvent(volumeNumber, barcodeImageBytes)); document.open(); // 创建表格(5列) PdfPTable table = new PdfPTable(7); // 设置表格宽度(占页面宽度的100%) table.setWidthPercentage(100); // 设置列宽比例,第4列(文件题名)设置得更宽 float[] columnWidths = {8f, 14f, 12f, 30f, 10f, 10f, 10f}; // 调整列宽比例,第4列文件题名占40% table.setWidths(columnWidths); // 设置中文字体 BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font chineseFont = new Font(bfChinese, 12); Font chineseFont1 = new Font(bfChinese, 16, Font.BOLD); // 获取卷号 String volumeNumber = dvss.get(0).getRecordId(); // 创建条形码 Image barcodeImage = Image.getInstance(barcodeService.generateBarcodeImage(volumeNumber)); barcodeImage.scaleToFit(80, 40); // 设置条形码大小 // 注册页面事件 DirectoryHeaderPageEvent pageEvent = new DirectoryHeaderPageEvent(volumeNumber, bfChinese, chineseFont1, chineseFont1, barcodeImage); writer.setPageEvent(pageEvent); // 设置适当的边距,为卷内封面、条形码和卷号预留空间 // setMargins(left, right, top, bottom) - 参数顺序:左、右、上、下 // 增大上边距为160,确保页眉内容有足够空间 document.setMargins(30, 30, 160, 30); document.open(); // 这里不再需要在第一页手动添加卷内封面内容,页面事件会处理 // 添加一个空白段落,确保表格内容不会与顶部元素重叠 Paragraph blankParagraph = new Paragraph(""); document.add(blankParagraph); // 创建表格(7列) PdfPTable table = new PdfPTable(7); // 设置表格宽度(占页面宽度的80%,居中显示) table.setWidthPercentage(90); table.setHorizontalAlignment(Element.ALIGN_CENTER); // 设置列宽比例,第4列(文件题名)和第2列(文件编号)设置得更宽 float[] columnWidths = {10f, 16f, 14f, 30f, 10f, 10f, 10f}; // 调整列宽比例,增加文件编号列的宽度 table.setWidths(columnWidths); // 设置表头行数,这样分页时每页都会自动重复表头 table.setHeaderRows(1); @@ -386,9 +417,9 @@ table.addCell(cell); //序号 //文件编号(档号) PdfPCell cell1 = new PdfPCell(new Paragraph(cellData.getDocumentNumber()==null?"":cellData.getDocumentNumber().toString(), chineseFont)); new Font(bfChinese, 12))); cell1.setHorizontalAlignment(Element.ALIGN_CENTER); cell1.setVerticalAlignment(Element.ALIGN_MIDDLE); @@ -470,7 +501,15 @@ // 添加内容 // String volumeNumber = "D3.4.1-05-2024-0002"; Paragraph recordInfo = new Paragraph("卷号:" + volumeNumber, chineseFont); // 创建卷号段落,使用Chunk来单独处理卷号值并添加下划线 Paragraph recordInfo = new Paragraph(); Chunk labelChunk = new Chunk("卷号:", chineseFont); Chunk valueChunk = new Chunk(volumeNumber, chineseFont); valueChunk.setUnderline(0.5f, -2f); // 添加下划线,0.5f是线宽,-2f是线与文字的距离 recordInfo.add(labelChunk); recordInfo.add(valueChunk); recordInfo.setAlignment(Element.ALIGN_RIGHT); document.add(recordInfo); int pcc = dmfs.size()<=1?0: dmfs.get(1).getCnt(); ruoyi-admin/pom.xml
@@ -17,6 +17,28 @@ <dependencies> <!-- Poi-tl Word 模板引擎--> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.9.1</version> </dependency> <dependency> <groupId>com.aspose</groupId> <artifactId>aspose-cells</artifactId> <version>8.5.2</version> <scope>system</scope> <systemPath>${project.basedir}/libs/aspose-cells-8.5.2.jar</systemPath> </dependency> <dependency> <groupId>com.aspose</groupId> <artifactId>aspose-words</artifactId> <version>14.9.0</version> <scope>system</scope> <systemPath>${project.basedir}/libs/aspose-words-14.9.0-jdk16.jar</systemPath> </dependency> <!-- spring-boot-devtools --> <!-- <dependency>--> <!-- <groupId>org.springframework.boot</groupId>--> ruoyi-admin/src/main/java/com/ruoyi/web/controller/archive/archiveAllExportController.java
@@ -1,29 +1,24 @@ package com.ruoyi.web.controller.archive; import com.aspose.cells.PdfCompliance; import com.aspose.words.License; import com.deepoove.poi.XWPFTemplate; import com.itextpdf.text.*; import com.itextpdf.text.Font; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.common.utils.poi.*; import com.ruoyi.domain.ArchiveRecords; import com.ruoyi.domain.DocumentMaterials; import com.ruoyi.domain.vo.*; import com.ruoyi.framework.web.domain.server.Sys; import com.ruoyi.service.IArchiveRecordsService; import com.ruoyi.service.IDocumentMaterialsService; import com.ruoyi.service.impl.BarcodeService; import com.ruoyi.service.impl.pdfGenerateService; import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellUtil; import org.apache.poi.xssf.usermodel.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -33,26 +28,18 @@ import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.lang.reflect.Field; import java.net.URLEncoder; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; import java.util.*; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import static org.apache.poi.hssf.usermodel.HSSFCell.*; // 导入ByteArrayOutputStream用于临时存储PDF数据 import java.io.ByteArrayOutputStream; @RestController @RequestMapping("/system/archiveAllExport") @@ -85,13 +72,256 @@ } } public boolean getLicense() { boolean result = false; try { InputStream is = null; ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); org.springframework.core.io.Resource[] resources = resolver.getResources("classpath:words.xml"); is = resources[0].getInputStream(); // ��Ŀ��lincense.xml��·�� License aposeLic = new License(); aposeLic.setLicense(is); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } public boolean getLicenseExcel() { boolean result = false; InputStream is = null; try { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); org.springframework.core.io.Resource[] resources = resolver.getResources("classpath:license.xml"); is = resources[0].getInputStream(); com.aspose.cells.License aposeLic = new com.aspose.cells.License(); aposeLic.setLicense(is); result = true; } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } /** * 将Excel指定子sheet转换为PDF并下载 * @param response 响应对象 * @param excelPath Excel文件路径 * @param sheetName 子sheet名称 * @throws Exception 异常信息 */ @PostMapping("/exportSheetToPdf") public void exportSheetToPdf(HttpServletResponse response, String excelPath, String sheetName) throws Exception { // 设置响应头 response.setContentType(MediaType.APPLICATION_PDF_VALUE); response.setHeader("Content-Disposition", "attachment; filename=sheet.pdf"); try { // 使用Aspose.Cells读取Excel文件 com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(excelPath); // 获取指定名称的子sheet com.aspose.cells.Worksheet sheet = wb.getWorksheets().get(sheetName); // 如果需要获取索引方式的子sheet,可以使用以下代码 // com.aspose.cells.Worksheet sheet = wb.getWorksheets().get(0); // 获取第一个sheet // 创建一个新的Workbook,只包含指定的sheet com.aspose.cells.Workbook newWorkbook = new com.aspose.cells.Workbook(); newWorkbook.getWorksheets().clear(); newWorkbook.getWorksheets().addCopy(sheet.getName()); // 将Excel转换为PDF字节数组 java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(); newWorkbook.save(baos, com.aspose.cells.SaveFormat.PDF); byte[] pdfBytes = baos.toByteArray(); // 将PDF输出到响应流 try (ServletOutputStream os = response.getOutputStream()) { os.write(pdfBytes); os.flush(); } } catch (Exception e) { e.printStackTrace(); throw e; } } /** * 将Excel所有子sheet转换为PDF并打包下载 * @param response 响应对象 * @param excelPath Excel文件路径 * @throws Exception 异常信息 */ @PostMapping("/exportAllSheetsToPdf") public void exportAllSheetsToPdf(HttpServletResponse response, String excelPath) throws Exception { // 设置响应头 response.setContentType("application/zip"); response.setHeader("Content-Disposition", "attachment; filename=all_sheets.zip"); try (ServletOutputStream os = response.getOutputStream(); ZipOutputStream zos = new ZipOutputStream(os)) { // 使用Aspose.Cells读取Excel文件 com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(excelPath); // 获取所有sheet com.aspose.cells.WorksheetCollection sheets = wb.getWorksheets(); // 遍历所有sheet for (int i = 0; i < sheets.getCount(); i++) { com.aspose.cells.Worksheet sheet = sheets.get(i); String sheetName = sheet.getName(); // 创建一个新的Workbook,只包含当前sheet com.aspose.cells.Workbook newWorkbook = new com.aspose.cells.Workbook(); newWorkbook.getWorksheets().clear(); newWorkbook.getWorksheets().addCopy(sheet.getName()); // 创建临时字节输出流 ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 将新的Workbook保存为PDF到临时流 newWorkbook.save(baos, com.aspose.cells.SaveFormat.PDF); byte[] pdfBytes = baos.toByteArray(); // 获取PDF总页数 // 将PDF添加到ZIP文件 ZipEntry entry = new ZipEntry(sheetName + ".pdf"); zos.putNextEntry(entry); zos.write(pdfBytes); zos.closeEntry(); System.out.println("Excel子sheet \"" + sheetName + "\" 转换为PDF成功"); } System.out.println("Excel所有子sheet转换为PDF并打包成功"); } catch (Exception e) { e.printStackTrace(); throw e; } } @PostMapping("/importTemplate") public void importTemplate(HttpServletResponse response) throws IOException { if (!getLicense()) { return; } try { // 获取 Word 模板所在路径 String filepath = "09-备考表.docx"; // 通过 XWPFTemplate 编译文件并渲染数据到模板中 XWPFTemplate template = XWPFTemplate.compile(filepath).render( new HashMap<String, Object>(){{ put("pages", 67); }}); String renderedDocPath = "rendered_output.docx"; File renderedFile = new File(renderedDocPath); try { // 将完成数据渲染的文档写出 template.writeAndClose(new FileOutputStream(renderedFile)); } catch (IOException e) { e.printStackTrace(); } File file = new File("test1.pdf"); FileOutputStream os = new FileOutputStream(file); com.aspose.words.Document doc = new com.aspose.words.Document("rendered_output.docx"); doc.save(os, com.aspose.words.SaveFormat.PDF);//ȫ��֧��DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF �ת�� } catch (Exception e) { e.printStackTrace(); } if (!getLicenseExcel()) { System.out.println("授权失败"); return ; } String inpath= "案卷封面.xls"; long old = System.currentTimeMillis(); // 设置响应头 response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment; filename=import_template.pdf"); try { // 读取Excel文件 com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(inpath); // 获取需要导出的sheet(索引从0开始) int targetSheetIndex = 1; com.aspose.cells.Worksheet targetSheet = wb.getWorksheets().get(targetSheetIndex); targetSheet.autoFitRows(true); System.out.println("当前sheet名称:" + targetSheet.getName()); System.out.println("当前sheet索引:" + targetSheet.getIndex()); // 隐藏所有其他工作表 for (int i = 0; i < wb.getWorksheets().getCount(); i++) { if (i != targetSheetIndex) { wb.getWorksheets().get(i).setVisible(false); } } // 设置活动工作表为目标工作表 wb.getWorksheets().setActiveSheetIndex(targetSheetIndex); // 创建PDF保存选项 com.aspose.cells.PdfSaveOptions pdfSaveOptions = new com.aspose.cells.PdfSaveOptions(); // 设置页面类型为A4 // 确保所有列在一页上 pdfSaveOptions.setAllColumnsInOnePagePerSheet(true); // 设置打印页面类型为默认 pdfSaveOptions.setCompliance(PdfCompliance.PDF_A_1_B); // 设置 PDF 兼容性标准 // 直接将原始工作簿保存为PDF(只包含可见的工作表) wb.save(response.getOutputStream(), pdfSaveOptions); long now = System.currentTimeMillis(); System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); } catch (Exception e) { e.printStackTrace(); // 打印详细错误信息 System.err.println("转换失败:" + e.getMessage()); e.printStackTrace(System.err); // 返回错误信息 response.reset(); response.setContentType("text/plain;charset=utf-8"); response.getWriter().write("导出失败:" + e.getMessage()); response.getWriter().flush(); } //导出卷面封面代码 ArchiveInfoVo aIV = iArchiveRecordsService.selectByRecordId(55L); @@ -299,6 +529,9 @@ } //09-备考表.pdf String pdf09Path = "09-备考表.pdf"; pdfGenerateService.generateFileStyleInfo(pdf09Path, aIV.getRecordId(), ids[i]); // 2. 压缩PDF到ZIP文件 // 添加PDF文件到ZIP @@ -549,6 +782,29 @@ } public com.aspose.cells.Workbook poiToAspose(org.apache.poi.ss.usermodel.Workbook poiWorkbook) throws Exception { // 临时文件路径 String tempFilePath = "temp_workbook.xlsx"; try { // 1. 将Apache POI Workbook保存为临时文件 try (FileOutputStream fos = new FileOutputStream(tempFilePath)) { poiWorkbook.write(fos); } // 2. 使用Aspose加载临时文件 com.aspose.cells.Workbook asposeWorkbook = new com.aspose.cells.Workbook(tempFilePath); return asposeWorkbook; } finally { // 清理临时文件 File tempFile = new File(tempFilePath); if (tempFile.exists()) { tempFile.delete(); } } } @@ -597,53 +853,99 @@ //压缩文件 zos = new ZipOutputStream(os); //pdf目录封面 String pdfPathF = "07-案卷封面.pdf"; pdfGenerateService.generatePdf(pdfPathF, id); // 2. 压缩PDF到ZIP文件 // 添加PDF文件到ZIP ZipEntry zipEntry = new ZipEntry(pdfPathF); zos.putNextEntry(zipEntry); // 读取PDF文件内容并写入ZIP try (FileInputStream fis = new FileInputStream(pdfPathF)) { byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zos.write(buffer, 0, len); } } //08-卷内卷内目录的pdf String pdf08Path= "08-卷内目录.pdf"; List<DocumentMaterialsVo> list3 = dsvs; pdfGenerateService.generateFileDirectoryPdf(pdf08Path, list3); ZipEntry zipEntry2 = new ZipEntry(pdf08Path); zos.putNextEntry(zipEntry2); // 读取PDF文件内容并写入ZIP try (FileInputStream fis = new FileInputStream(pdf08Path)) { byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zos.write(buffer, 0, len); } } //09-备考表.pdf String pdf09Path = "09-备考表.pdf"; pdfGenerateService.generateFileStyleInfo(pdf09Path, aIV.getRecordId(), id); // 2. 压缩PDF到ZIP文件 // 添加PDF文件到ZIP ZipEntry zipEntry1 = new ZipEntry(pdf09Path); zos.putNextEntry(zipEntry1); // pdfGenerateService.generateFileStyleInfo(pdf09Path, aIV.getRecordId(), id); //拿到相关数据 List<DocumentMaterialFileStyle> dmfs = documentMaterialsService.findFileStyleInfo(Math.toIntExact(id)); // 读取PDF文件内容并写入ZIP try (FileInputStream fis = new FileInputStream(pdf09Path)) { byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zos.write(buffer, 0, len); } LocalDate currentDate = LocalDate.now(); String cdt = currentDate.getYear()+"年"+currentDate.getMonthValue()+"月"+currentDate.getDayOfMonth()+"日"; HashMap<String, Object> hs = new HashMap<String, Object>(); if(dmfs.isEmpty()) { //全部数据值为0 hs.put("pages", 0); hs.put("volumeNumber", aIV.getRecordId()); hs.put("time", cdt); } else { int pcc = dmfs.size()<=1?0: dmfs.get(1).getCnt(); int oth = dmfs.size()<=2?0: dmfs.get(2).getCnt(); int allCnt = dmfs.get(0).getCnt() + pcc + oth; hs.put("pages", allCnt); hs.put("volumeNumber", aIV.getRecordId()); hs.put("time", cdt); } if (!getLicense()) { System.out.println("没有相关证书!"); } try { // 获取 Word 模板所在路径 String filepath = "09-备考表.docx"; // 通过 XWPFTemplate 编译文件并渲染数据到模板中 XWPFTemplate template = XWPFTemplate.compile(filepath).render(hs ); String renderedDocPath = "rendered_output.docx"; File renderedFile = new File(renderedDocPath); try { // 将完成数据渲染的文档写出 template.writeAndClose(new FileOutputStream(renderedFile)); } catch (IOException e) { e.printStackTrace(); } com.aspose.words.Document doc = new com.aspose.words.Document("rendered_output.docx"); // 创建临时字节输出流 ByteArrayOutputStream baobk = new ByteArrayOutputStream(); // 将Word文档转换为PDF字节数组 doc.save(baobk, com.aspose.words.SaveFormat.PDF);//ȫ��֧��DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF �ת�� // byte[] pdfBytes = baobk.toByteArray(); // 获取PDF总页数 // 将PDF添加到ZIP文件 ZipEntry entry09 = new ZipEntry(pdf09Path); zos.putNextEntry(entry09); baobk.writeTo(zos); } catch (Exception e) { e.printStackTrace(); } com.aspose.words.Document doc = new com.aspose.words.Document("09-备考表.docx"); // // 压缩PDF到ZIP文件 // // 添加PDF文件到ZIP // ZipEntry zipEntry1 = new ZipEntry(pdf09Path); // zos.putNextEntry(zipEntry1); // // // 读取PDF文件内容并写入ZIP // try (FileInputStream fis = new FileInputStream(pdf09Path)) { // byte[] buffer = new byte[1024]; // int len; // while ((len = fis.read(buffer)) > 0) { // zos.write(buffer, 0, len); // } // } @@ -670,14 +972,72 @@ // System.out.println(bos2); zos.putNextEntry(entryiv); // ExcelUtil<ArchiveInfoVo> utilsv = new ExcelUtil<ArchiveInfoVo>(ArchiveInfoVo.class); // bos2.writeTo(zos); //pdf目录封面 String pdfPathF = "07-案卷封面.pdf"; // pdfGenerateService.generatePdf(pdfPathF, id); try { if (!getLicenseExcel()) { System.out.println("授权失败"); // return ; } // 读取Excel文件 com.aspose.cells.Workbook wb = poiToAspose(util3.getWb()); // 获取需要导出的sheet(索引从0开始) int targetSheetIndex = 1; com.aspose.cells.Worksheet targetSheet = wb.getWorksheets().get(targetSheetIndex); targetSheet.autoFitRows(true); System.out.println("当前sheet名称:" + targetSheet.getName()); System.out.println("当前sheet索引:" + targetSheet.getIndex()); // 隐藏所有其他工作表 for (int i = 0; i < wb.getWorksheets().getCount(); i++) { if (i != targetSheetIndex) { wb.getWorksheets().get(i).setVisible(false); } } // 设置活动工作表为目标工作表 wb.getWorksheets().setActiveSheetIndex(targetSheetIndex); // 创建PDF保存选项 com.aspose.cells.PdfSaveOptions pdfSaveOptions = new com.aspose.cells.PdfSaveOptions(); pdfSaveOptions.setCompliance(com.aspose.cells.PdfCompliance.PDF_A_1_B); // 创建临时字节输出流 ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 将新的Workbook保存为PDF到临时流 // newWorkbook.save(baos, com.aspose.cells.SaveFormat.PDF); wb.save(baos, pdfSaveOptions); // 将PDF添加到ZIP文件 ZipEntry entry = new ZipEntry(pdfPathF); zos.putNextEntry(entry); zos.write(baos.toByteArray()); // zos.closeEntry(); // 直接将原始工作簿保存为PDF(只包含可见的工作表) long now = System.currentTimeMillis(); // System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); } catch (Exception e) { e.printStackTrace(); // 打印详细错误信息 System.err.println("转换失败:" + e.getMessage()); e.printStackTrace(System.err); } // // ByteOutputStream boss = new ByteOutputStream(); // List<ArchiveInfoVo> aivs = new ArrayList<>(); // aivs.add(aIV); // utilsv.byteOutputStreamExcel(boss, aivs,"Date List", ""); bos2.writeTo(zos); //写入电子目录 xsxl ZipEntry entry = new ZipEntry("电子文件目录" + ".xls"); @@ -695,7 +1055,7 @@ String recordId = dsvs.get(0).getRecordId(); byte[] imgr = barcodeService.generateBarcodeImage(recordId); ExcelExp e1 = new ExcelExp("卷内目录数据",dsvs, DocumentMaterialsVo.class); ExcelExp e2 = new ExcelExp("卷内数据", list2, recordId, imgr, DocumentMaterialsVoSmall.class); ExcelExp e2 = new ExcelExp("卷内目录", list2, recordId, imgr, DocumentMaterialsVoSmall.class); List<ExcelExp> mysheet = new ArrayList<ExcelExp>(); mysheet.add(e1); mysheet.add(e2); @@ -711,6 +1071,78 @@ // util1.byteOutputStreamExcel(bos1, dsvs,"Date List", ""); bos1.writeTo(zos); //把excel转为pdf //08-卷内卷内目录的pdf String pdf08Path= "08-卷内目录.pdf"; try { if (!getLicenseExcel()) { System.out.println("授权失败"); // return ; } // 读取Excel文件 com.aspose.cells.Workbook wb1 = poiToAspose(util2.getWb()); // 获取需要导出的sheet(索引从0开始) int targetSheetIndex = 1; com.aspose.cells.Worksheet targetSheet = wb1.getWorksheets().get(targetSheetIndex); targetSheet.autoFitRows(true); System.out.println("当前sheet名称:" + targetSheet.getName()); System.out.println("当前sheet索引:" + targetSheet.getIndex()); // 隐藏所有其他工作表 for (int i = 0; i < wb1.getWorksheets().getCount(); i++) { if (i != targetSheetIndex) { wb1.getWorksheets().get(i).setVisible(false); } } // 设置活动工作表为目标工作表 wb1.getWorksheets().setActiveSheetIndex(targetSheetIndex); // 创建PDF保存选项 com.aspose.cells.PdfSaveOptions pdfSaveOptions = new com.aspose.cells.PdfSaveOptions(); pdfSaveOptions.setCompliance(com.aspose.cells.PdfCompliance.PDF_A_1_B); // 创建临时字节输出流 ByteArrayOutputStream baosm = new ByteArrayOutputStream(); // 将新的Workbook保存为PDF到临时流 // newWorkbook.save(baos, com.aspose.cells.SaveFormat.PDF); wb1.save(baosm, pdfSaveOptions); // 将PDF添加到ZIP文件 ZipEntry entry2 = new ZipEntry(pdf08Path); zos.putNextEntry(entry2); zos.write(baosm.toByteArray()); // zos.closeEntry(); // 直接将原始工作簿保存为PDF(只包含可见的工作表) long now = System.currentTimeMillis(); // System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); } catch (Exception e) { e.printStackTrace(); // 打印详细错误信息 System.err.println("转换失败:" + e.getMessage()); e.printStackTrace(System.err); } //List<DocumentMaterialsVo> list3 = dsvs; // pdfGenerateService.generateFileDirectoryPdf(pdf08Path, list3); // ZipEntry zipEntry2 = new ZipEntry(pdf08Path); // zos.putNextEntry(zipEntry2); // // // 读取PDF文件内容并写入ZIP // try (FileInputStream fis = new FileInputStream(pdf08Path)) { // byte[] buffer = new byte[1024]; // int len; // while ((len = fis.read(buffer)) > 0) { // zos.write(buffer, 0, len); // } // } @@ -793,3 +1225,7 @@ } } ruoyi-admin/src/main/resources/license.xml
New file @@ -0,0 +1,12 @@ <License> <Data> <Products> <Product>Aspose.Total for Java</Product> </Products> <EditionType>Enterprise</EditionType> <SubscriptionExpiry>20991231</SubscriptionExpiry> <LicenseExpiry>20991231</LicenseExpiry> <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber> </Data> <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature> </License> ruoyi-common/pom.xml
@@ -141,6 +141,12 @@ <version>3.5.5</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13</version> <scope>compile</scope> </dependency> </dependencies> <!-- <build>--> ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java
@@ -149,6 +149,11 @@ public IndexedColors backgroundColor() default IndexedColors.WHITE; /** * 导出单元格字体名称 */ public String fontName() default "Arial"; /** * 导出单元格字体颜色 */ public IndexedColors color() default IndexedColors.BLACK; @@ -173,6 +178,8 @@ */ Type type() default Type.ALL; public int headerFontSize() default 12; public enum Type { ALL(0), EXPORT(1), IMPORT(2); ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtilManySheet.java
@@ -62,6 +62,14 @@ */ private Excel.Type type; public Workbook getWb() { return wb; } public void setWb(Workbook wb) { this.wb = wb; } /** * 工作薄对象 */ @@ -353,8 +361,11 @@ String recordId = list.get(index).getRecordId(); row.createCell(5).setCellValue(recordId); row = sheet.createRow(3); column = 0; // // 添加总页数和当前页码信息 // row.createCell(5).setCellValue("总页数: " + list.size() + ", 当前页: " + (index + 1)); // row = sheet.createRow(4); column = 0; } else { // 普通sheet处理 // recordId = (DocumentMaterialsVo)list.get(0) @@ -530,7 +541,7 @@ style.setWrapText(true); Font headerFont = wb.createFont(); headerFont.setFontName(excel.headerFontName()); headerFont.setFontHeightInPoints((short) 10); headerFont.setFontHeightInPoints((short) 12); headerFont.setBold(excel.headerFontBold()); headerFont.setColor(excel.headerColor().index); style.setFont(headerFont); @@ -1015,4 +1026,4 @@ } return val; } } } ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtilManySheetSecond.java
@@ -14,21 +14,18 @@ import com.ruoyi.common.utils.reflect.ReflectUtils; import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.hssf.usermodel.HSSFClientAnchor; import org.apache.poi.hssf.usermodel.HSSFDataValidation; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFClientAnchor; import org.apache.poi.hssf.usermodel.HSSFDataValidation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -37,6 +34,7 @@ import java.text.DecimalFormat; import java.util.*; import java.util.stream.Collectors; /** * Excel相关处理 @@ -60,6 +58,14 @@ * 导出类型(EXPORT:导出数据;IMPORT:导入模板) */ private Excel.Type type; public Workbook getWb() { return wb; } public void setWb(Workbook wb) { this.wb = wb; } /** * 工作薄对象 @@ -293,7 +299,7 @@ row = sheet.createRow(0); sheet.addMergedRegion(new CellRangeAddress(2, 3, 0, 1)); row = sheet.createRow(2); row.setHeightInPoints(120); // 设置行高为20磅 row.setHeightInPoints(100); // 设置行高为20磅 //拿到图片 // 创建单元格并添加图片 @@ -308,11 +314,11 @@ // 创建单元格 Cell qrCell = sheet.createRow(2).createCell(1); // 设置行高足够高以显示二维码 sheet.getRow(2).setHeightInPoints(120); sheet.getRow(2).setHeightInPoints(100); // 二维码需要较大的列宽来显示,设置之前先保存当前列宽 int currentColumnWidth = sheet.getColumnWidth(1); // 设置足够宽的列宽以显示二维码 sheet.setColumnWidth(1, 60 * 256); sheet.setColumnWidth(1, 40 * 256); // 创建图片锚点,设置在第2行第2列 // 二维码显示在右上角且不填满整个格子 @@ -330,8 +336,17 @@ String [] tits = {"档 号:","档案馆(室)号:","缩 微 号: ","发 文 号:", "案 卷 题 名:","编 制 日 期:","编 制 单 位:","保 管 期 限:","密 级:"}; // 以"档案馆 (室) 号:"为基准,统一所有标题的长度和格式 String [] tits = { "档 号:", "档案馆 (室) 号:", "缩 微 号:", "发 文 号:", "案 卷 题 名:", "编 制 日 期:", "编 制 单 位:", "保 管 期 限:", "密 级:"}; List tmp = list.get(index).getDataset(); Object obj = tmp.get(0); @@ -356,23 +371,25 @@ if(i > 3) row = sheet.createRow(i+7); // row.setHeight((short) 30); row.setHeightInPoints(40); // 设置行高为20磅 // row.createCell(0) // 不设置固定行高,后续使用autoSizeRow自动调整 cell = row.createCell(0); // 根据用户需求设置第二子表格的列宽 // 第一列宽度设置为27 // 第二列宽度设置为51 // 使用与addCell方法相同的计算公式设置列宽 sheet.setColumnWidth(0, (int) ((27 + 0.72) * 256)); // 第一列:宽度27 sheet.setColumnWidth(1, (int) ((51 + 0.72) * 256)); // 第二列:宽度51 sheet.setColumnWidth(0, (int) ((29 + 0.72) * 256)); // 第一列:宽度27 sheet.setColumnWidth(1, (int) ((52 + 0.72) * 256)); // 第二列:宽度51 CellStyle style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.RIGHT); style.setVerticalAlignment(VerticalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); // 设置垂直居中 // style.setAlignment(VerticalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.BOTTOM); // 设置垂直下对齐 style.setWrapText(true); // 设置自动换行 // 设置字体为Times New Roman 18号 Font font = wb.createFont(); font.setBold(true); font.setFontName("Times New Roman"); font.setFontHeightInPoints((short) 18); style.setFont(font); style.setWrapText(true); // 设置自动换行 cell.setCellStyle(style); @@ -381,9 +398,26 @@ CellStyle style1 = wb.createCellStyle(); style1.setBorderBottom(BorderStyle.THIN); // 添加下划线 style1.setWrapText(true); // 设置自动换行 style1.setVerticalAlignment(VerticalAlignment.CENTER); style1.setVerticalAlignment(VerticalAlignment.BOTTOM); // 设置垂直下对齐 // 设置内容字体为Times New Roman 16号 Font contentFont = wb.createFont(); contentFont.setFontName("Times New Roman"); contentFont.setFontHeightInPoints((short) 16); // 当i==4时,为文字添加下划线 if(i==4) { contentFont.setUnderline(Font.U_SINGLE); // 添加单下划线 } style1.setFont(contentFont); cel.setCellStyle(style1); if(i==4) { // 确保案 卷 题 名:这一行能根据内容长度自动换行 style1.setWrapText(true); // 明确设置自动换行 cel.setCellStyle(style1); } // 处理日期格式化,特别是"编 制 日 期:"这一行 if (i == 5 && fieldValue instanceof Date) { // 设置日期格式为yyyy-MM-dd @@ -391,6 +425,21 @@ cel.setCellValue(dateStr); } else { cel.setCellValue(fieldValue.toString()); } // 对于i==4的情况,确保行高能根据内容自动调整 if(i==4) { // 设置行高为自动调整(-1表示自动高度) row.setHeight((short) -1); // 不限制最大行高,允许根据内容自动调整 } else { // 使用setHeight方法设置行高为自动调整(-1表示自动高度) row.setHeight((short) -1); // 确保行高至少为40磅,但不限制最大行高 if (row.getHeightInPoints() < 40) { row.setHeightInPoints(40); } } // sheet.setColumnWidth(0, 60 * 256); i++; @@ -400,7 +449,7 @@ // 设置行高为自动调整 row.setHeight((short) -1); // row.setHeight((short) 30); row.setHeightInPoints(40); // 设置行高为20磅 row.setHeightInPoints(20); // 设置行高为20磅 row = sheet.createRow(9); //设置条形码 // 设置条形码 @@ -409,23 +458,23 @@ // 创建单元格 Cell barcodeCell = sheet.createRow(9).createCell(0); // 设置行高足够高以显示条形码 sheet.getRow(9).setHeightInPoints(70); sheet.getRow(9).setHeightInPoints(40); // 设置列宽足够宽以显示条形码,先保存当前列宽 int currentColumnWidth0 = sheet.getColumnWidth(0); sheet.setColumnWidth(0, 40 * 256); // 创建图片锚点,设置在第10行第1列 // 条形码居中且不超出第二个格子 // 调整结束列索引和位置参数 // 增加dx1值,使条形码整体向右移动 ClientAnchor anchor1 = new HSSFClientAnchor(300, 50, 900, 200, (short) 0, 9, (short) 1, 10); ClientAnchor anchor1 = new HSSFClientAnchor(660, 50, 900, 200, (short) 0, 9, (short) 1, 10); // 设置图片位置和大小 anchor1.setAnchorType(ClientAnchor.AnchorType.MOVE_DONT_RESIZE); // 添加图片到工作表 getDrawingPatriarch(sheet).createPicture(anchor1, wb.addPicture(dat, getImageType(dat))); // 条形码添加完成后,恢复原来的列宽设置 sheet.setColumnWidth(0, currentColumnWidth0); } @@ -611,7 +660,7 @@ for (Object[] os : fields) { Excel excel = (Excel) os[1]; String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor()); String key = StringUtils.format("header_{}_{}_{}_{}_{}", excel.headerColor(), excel.headerBackgroundColor(), excel.headerFontName(), excel.headerFontBold(), excel.headerFontSize()); if (!headerStyles.containsKey(key)) { style = wb.createCellStyle(); @@ -626,8 +675,8 @@ style.setFillPattern(FillPatternType.SOLID_FOREGROUND); }*/ Font headerFont = wb.createFont(); headerFont.setFontName("Arial"); headerFont.setFontHeightInPoints((short) 10); headerFont.setFontName(excel.headerFontName()); headerFont.setFontHeightInPoints((short) excel.headerFontSize()); // 使用Excel注解中的headerFontSize属性 headerFont.setBold(excel.headerFontBold()); headerFont.setColor(excel.headerColor().index); style.setFont(headerFont); @@ -681,7 +730,7 @@ cell.setCellValue(attr.name()); setDataValidation(attr, row, column); // 根据Excel注解动态选择表头样式 String key = StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()); String key = StringUtils.format("header_{}_{}_{}_{}_{}", attr.headerColor(), attr.headerBackgroundColor(), attr.headerFontName(), attr.headerFontBold(), attr.headerFontSize()); cell.setCellStyle(styles.get(key)); return cell; } @@ -1124,4 +1173,27 @@ } return val; } /** * 将Apache POI的Workbook转换为Aspose.Cells的Workbook * * @param poiWorkbook Apache POI的Workbook对象 * @return Aspose.Cells的Workbook对象 * @throws IOException IO异常 */ }