| | |
| | | import com.itextpdf.text.Font; |
| | | import com.itextpdf.text.Image; |
| | | import com.itextpdf.text.Rectangle; |
| | | 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.itextpdf.text.pdf.*; |
| | | import com.ruoyi.common.config.RuoYiConfig; |
| | | import com.ruoyi.domain.ArchiveRecords; |
| | | import com.ruoyi.domain.vo.DocumentMaterialFileStyle; |
| | |
| | | import com.ruoyi.domain.vo.DocumentMaterialsVoSmall; |
| | | import com.ruoyi.service.IArchiveRecordsService; |
| | | import com.ruoyi.service.IDocumentMaterialsService; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.poi.ss.usermodel.*; |
| | | import org.apache.poi.xssf.usermodel.*; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import java.time.LocalDate; |
| | | import java.time.ZoneId; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | // 自定义页面事件类,用于在每个新页面添加卷内封面和卷号 |
| | | private class DirectoryHeaderPageEvent extends PdfPageEventHelper { |
| | | private String volumeNumber; |
| | | private BaseFont bfChinese; |
| | | private Font chineseFont; |
| | | private Font chineseFont1; |
| | | private Image barcodeImage; |
| | | |
| | | public DirectoryHeaderPageEvent(String volumeNumber, BaseFont bfChinese, Font chineseFont, Font chineseFont1, Image barcodeImage) { |
| | | this.volumeNumber = volumeNumber; |
| | | this.bfChinese = bfChinese; |
| | | this.chineseFont = chineseFont; |
| | | this.chineseFont1 = chineseFont1; |
| | | this.barcodeImage = barcodeImage; |
| | | } |
| | | |
| | | @Override |
| | | public void onStartPage(PdfWriter writer, Document document) { |
| | | try { |
| | | PdfContentByte cb = writer.getDirectContent(); |
| | | float pageWidth = document.getPageSize().getWidth(); |
| | | float pageHeight = document.getPageSize().getHeight(); |
| | | |
| | | // 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); |
| | | |
| | | // 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(); |
| | | |
| | | // 3. 添加卷号(居右显示,标题下方) |
| | | String label = "卷号:"; |
| | | String value = volumeNumber; |
| | | float recordInfoX = pageWidth - 30; |
| | | float recordInfoY = pageHeight - 130; // 页面顶部下方130点 |
| | | |
| | | // 先绘制标签"卷号:" |
| | | 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(); |
| | | |
| | | // 计算值的位置并绘制下划线 |
| | | float labelWidth = bfChinese.getWidthPoint(label, 12); |
| | | float valueWidth = bfChinese.getWidthPoint(value, 12); |
| | | float underlineStartX = recordInfoX - valueWidth; |
| | | float underlineEndX = recordInfoX; |
| | | float underlineY = recordInfoY - 2; |
| | | |
| | | cb.setColorStroke(BaseColor.BLACK); |
| | | cb.setLineWidth(0.5f); |
| | | cb.moveTo(underlineStartX, underlineY); |
| | | cb.lineTo(underlineEndX, underlineY); |
| | | cb.stroke(); |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | //导出卷内目录的pdf |
| | | public void generateFileDirectoryPdf(String pdfPath,List<DocumentMaterialsVo> dvss) throws DocumentException, IOException { |
| | | Document document = new Document(); |
| | | PdfWriter.getInstance(document, new FileOutputStream(pdfPath)); |
| | | document.open(); |
| | | |
| | | // 创建表格(5列) |
| | | PdfPTable table = new PdfPTable(7); |
| | | |
| | | // 设置表格宽度(占页面宽度的100%) |
| | | table.setWidthPercentage(100); |
| | | |
| | | |
| | | //添加条形码 |
| | | String volumeNumber = dvss.get(0).getRecordId(); |
| | | Image img = Image.getInstance(barcodeService.generateBarcodeImage(volumeNumber)); |
| | | // 设置图片在PDF中的位置(可选) |
| | | // img.setAbsolutePosition(100, 100); |
| | | // 将图片添加到PDF文档中 |
| | | 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); |
| | | // 创建表格并设置列宽比例 |
| | | float[] columnWidths = {35f, 65f}; // 第一列30%,第二列70% |
| | | PdfPTable table1 = new PdfPTable(columnWidths); |
| | | // PdfPTable table = new PdfPTable(2); |
| | | table1.setWidthPercentage(80); // 增大表格宽度百分比 |
| | | table1.setHorizontalAlignment(Element.ALIGN_LEFT); // 设置表格整体居中 |
| | | table1.setSpacingBefore(30f); // 设置表格前间距 |
| | | |
| | | table1.addCell(pdfPCell); |
| | | |
| | | document.add(table1); |
| | | |
| | | |
| | | // 添加表头 |
| | | PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdfPath)); |
| | | |
| | | // 设置中文字体 |
| | | 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); |
| | | // 添加标题 |
| | | Paragraph title = new Paragraph("卷 内 目 录", chineseFont1); |
| | | title.setAlignment(Element.ALIGN_CENTER); |
| | | document.add(title); |
| | | Paragraph withNewLine = new Paragraph("\n"); |
| | | document.add(withNewLine); |
| | | document.add(withNewLine); |
| | | |
| | | // 获取卷号 |
| | | 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); |
| | | |
| | | |
| | | //添加卷号 |
| | | Paragraph recordInfo = new Paragraph("卷号:" + volumeNumber, chineseFont); |
| | | recordInfo.setAlignment(Element.ALIGN_RIGHT); |
| | | document.add(recordInfo); |
| | | |
| | | document.add(withNewLine); |
| | | document.add(withNewLine); |
| | | // 设置表格宽度(占页面宽度的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); |
| | | |
| | | // 添加表头 |
| | | String[] headers = {"序号", "文件编号", "责任者", "文件题名", "日期", "页号", "备注"}; |
| | | for (String header : headers) { |
| | | PdfPCell cell = new PdfPCell(new Paragraph(header, |
| | |
| | | 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); |
| | | |
| | |
| | | |
| | | // 创建PDF文档 |
| | | List<DocumentMaterialFileStyle> dmfs = documentMaterialsService.findFileStyleInfo(Math.toIntExact(id)); |
| | | if(dmfs.isEmpty()) |
| | | return; |
| | | |
| | | |
| | | System.out.println(dmfs); |
| | | PdfWriter.getInstance(document, new FileOutputStream("09-备考表"+".pdf")); |
| | | document.open(); |
| | | // 设置中文字体 |
| | |
| | | |
| | | // 添加内容 |
| | | // 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 allCnt = dmfs.get(0).getCnt() + dmfs.get(1).getCnt() + dmfs.get(2).getCnt(); |
| | | 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; |
| | | document.add(new Paragraph(" 本 案 卷 共 有 文 件 材 料 " + allCnt + " 页"+",其中:文字材料 " + |
| | | dmfs.get(1).getCnt() + " 页"+",图样材料 " + dmfs.get(2).getCnt() + " 页"+",照片 " + dmfs.get(0).getCnt() + " 张", chineseFont)); |
| | | pcc + " 页"+",图样材料 " + oth + " 页"+",照片 " + dmfs.get(0).getCnt() + " 张", chineseFont)); |
| | | |
| | | |
| | | document.add(new Paragraph("说明: ", chineseFont)); |
| | |
| | | PdfWriter.getInstance(document, new FileOutputStream(pdfPath)); |
| | | document.open(); |
| | | |
| | | String [] tits = {"档 号:","档案馆(室)号:","缩 微 号: ","发 文 号:", |
| | | "案 卷 题 名:","编 制 日 期:","编 制 单 位:","保 管 期 限:","密 级:"}; |
| | | String [] tits = {"档号:","档案馆(室)号:","缩微号:","发文号:", |
| | | "案卷题名:","编制日期:","编制单位:","保管期限:","密级:"}; |
| | | ArchiveRecords ard = iArchiveRecordsService.selectArchiveRecordsById(id); |
| | | |
| | | |
| | |
| | | ; |
| | | System.out.println("当前日期: " + date); |
| | | |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | formattedDate = date.format(formatter); |
| | | } |
| | | |
| | |
| | | float[] columnWidths = {35f, 65f}; // 第一列30%,第二列70% |
| | | PdfPTable table = new PdfPTable(columnWidths); |
| | | // PdfPTable table = new PdfPTable(2); |
| | | table.setWidthPercentage(80); // 增大表格宽度百分比 |
| | | table.setWidthPercentage(78); // 减小表格宽度百分比使两列更紧凑 |
| | | table.setHorizontalAlignment(Element.ALIGN_LEFT); // 设置表格整体居中 |
| | | table.setSpacingBefore(30f); // 设置表格前间距 |
| | | table.setSpacingAfter(90f); // 设置表格后间距 |
| | |
| | | |
| | | |
| | | |
| | | // 先计算所有标题的最长长度 |
| | | int maxTitleLength = 0; |
| | | for (String tit : tits) { |
| | | maxTitleLength = Math.max(maxTitleLength, tit.length()-1); |
| | | } |
| | | |
| | | for(int i = 0; i < tits.length; i++) { |
| | | // 使用PdfPTable实现精确对齐 |
| | | |
| | | // 第一行:档号 |
| | | PdfPCell labelCell1 = new PdfPCell(new Phrase(tits[i], chineseFont)); |
| | | labelCell1.setHorizontalAlignment(Element.ALIGN_RIGHT); // 设置右对齐 |
| | | // 实现对齐:在文字之间填充空格,使所有标题总长度相同 |
| | | String originalText = tits[i]; |
| | | |
| | | // 计算需要添加的空格数 |
| | | int spacesToAdd = maxTitleLength - originalText.length(); |
| | | |
| | | String formattedText = originalText; |
| | | if (spacesToAdd > 0) { |
| | | // 在冒号前的文字之间均匀分配填充空格 |
| | | if (originalText.contains(":")) { |
| | | int colonIndex = originalText.indexOf(":"); |
| | | String textBeforeColon = originalText.substring(0, colonIndex); |
| | | String textAfterColon = originalText.substring(colonIndex); |
| | | |
| | | // 如果冒号前只有一个字符,直接在后面加空格 |
| | | if (textBeforeColon.length() == 1) { |
| | | String fullWidthSpaces = StringUtils.repeat(" ", spacesToAdd); |
| | | formattedText = textBeforeColon + fullWidthSpaces + textAfterColon; |
| | | } else if (textBeforeColon.length() > 1) { |
| | | // 在文字之间均匀分配空格 |
| | | StringBuilder sb = new StringBuilder(); |
| | | int chars = textBeforeColon.length(); |
| | | int spacesPerGap = spacesToAdd / (chars - 1); |
| | | int extraSpaces = spacesToAdd % (chars - 1); |
| | | |
| | | for (int j = 0; j < chars; j++) { |
| | | sb.append(textBeforeColon.charAt(j)); |
| | | if (j < chars - 1) { |
| | | // 添加基本空格 |
| | | sb.append(StringUtils.repeat(" ", spacesPerGap)); |
| | | // 分配剩余空格 |
| | | if (j < extraSpaces) { |
| | | sb.append(" "); |
| | | } |
| | | } |
| | | } |
| | | sb.append(textAfterColon); |
| | | formattedText = sb.toString(); |
| | | } |
| | | } else { |
| | | // 如果没有冒号,直接在末尾加空格(应该不会出现这种情况) |
| | | String fullWidthSpaces = StringUtils.repeat(" ", spacesToAdd); |
| | | formattedText = originalText + fullWidthSpaces; |
| | | } |
| | | } |
| | | |
| | | PdfPCell labelCell1 = new PdfPCell(new Phrase(formattedText, chineseFont)); |
| | | labelCell1.setHorizontalAlignment(Element.ALIGN_RIGHT); // 单元格右对齐 |
| | | |
| | | labelCell1.setBorder(Rectangle.NO_BORDER); |
| | | // PdfPCell valueCell1 = new PdfPCell(new Phrase(cons[i], chineseFont)); |
| | |
| | | labelCell1.setPaddingTop(10f); // 上内边距10单位 |
| | | labelCell1.setPaddingBottom(10f); // 下内边距10单位 |
| | | labelCell1.setPaddingLeft(15f); // 左内边距15单位 |
| | | labelCell1.setPaddingRight(15f); // 右内边距15单位 |
| | | labelCell1.setPaddingRight(0f); // 右内边距15单位 |
| | | |
| | | |
| | | PdfPCell valueCell1 = new PdfPCell(new Phrase(cons[i], chineseFont)); |
| | | valueCell1.setBorder(Rectangle.NO_BORDER); |
| | | valueCell1.setUseBorderPadding(true); |
| | | valueCell1.setUseBorderPadding(false); // 禁用边框内边距计算 |
| | | valueCell1.setBorderWidthBottom(0.5f); // 设置底部边框作为下划线 |
| | | valueCell1.setMinimumHeight(30); |
| | | valueCell1.setPaddingTop(10f); // 上内边距10单位 |
| | | valueCell1.setPaddingBottom(10f); // 下内边距10单位 |
| | | valueCell1.setPaddingLeft(15f); // 左内边距15单位 |
| | | valueCell1.setPaddingLeft(0f); // 左内边距0单位 |
| | | valueCell1.setExtraParagraphSpace(0f); // 移除段落额外空间 |
| | | valueCell1.setPaddingRight(15f); // 右内边距15单位 |
| | | table.addCell(labelCell1); |
| | | table.addCell(valueCell1); |
| | |
| | | PdfPCell pdfPCell1 = new PdfPCell(img1); |
| | | pdfPCell1.setBorder(Rectangle.NO_BORDER); // 移除单元格边框 |
| | | |
| | | pdfPCell1.setMinimumHeight(40); |
| | | pdfPCell1.setMinimumHeight(20); |
| | | pdfPCell1.setUseAscender(true); // 设置可以居中 |
| | | pdfPCell1.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT); // 设置水平居中 |
| | | pdfPCell1.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); // 设置垂直居中 |