package com.ruoyi.service.impl; import cn.hutool.extra.qrcode.QrCodeUtil; import cn.hutool.extra.qrcode.QrConfig; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.itextpdf.text.*; import com.itextpdf.text.Font; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; 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.DocumentMaterialsVo; 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 org.springframework.stereotype.Service; import javax.imageio.ImageIO; import java.awt.*; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.*; import java.text.SimpleDateFormat; 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; @Service public class pdfGenerateService { @Autowired private BarcodeService barcodeService; @Autowired private IDocumentMaterialsService documentMaterialsService; @Autowired private IArchiveRecordsService iArchiveRecordsService; //生产二维码 public byte[] createQrCodeN(String content, int width, int height) throws IOException { QrConfig config = new QrConfig(width, height); config.setMargin(3); // 高纠错级别 config.setErrorCorrection(ErrorCorrectionLevel.H); // 设置前景色,既二维码颜色(自行选择颜色修改) config.setForeColor(new Color(11, 11, 11).getRGB()); // 设置背景色(灰色)需要背景色时候打开链接 config.setBackColor(new Color(242,242,242).getRGB()); BufferedImage bufferedImage = QrCodeUtil.generate(// content, //二维码内容 config ); System.out.println(bufferedImage); System.out.println("---02340230949394"); ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", os); // ImageIO.write(bufferedImage, "jpg", new File("outputImage.jpg")); return os.toByteArray(); } private void handleXSSFImages(XSSFSheet sheet, Document pdfDoc) throws Exception { XSSFDrawing drawing = sheet.getDrawingPatriarch(); if (drawing == null) return; for (XSSFShape shape : drawing.getShapes()) { if (shape instanceof XSSFPicture) { XSSFPicture pic = (XSSFPicture)shape; XSSFClientAnchor anchor = pic.getPreferredSize(); // 获取图片数据 byte[] bytes = pic.getPictureData().getData(); Image pdfImage = Image.getInstance(bytes); // 设置图片位置和大小 float imageWidth = pdfImage.getWidth(); float imageHeight = pdfImage.getHeight(); float scale = Math.min( (PageSize.A4.getWidth() - 100) / imageWidth, (PageSize.A4.getHeight() - 100) / imageHeight ); pdfImage.scaleAbsolute(imageWidth * scale, imageHeight * scale); // 添加图片到PDF pdfDoc.add(pdfImage); pdfDoc.add(Chunk.NEWLINE); } } } private static String getCellValue(Cell cell,FormulaEvaluator evaluator) { // System.out.println(cell); if (cell == null) return ""; CellValue cellValue = evaluator.evaluate(cell); if(cellValue==null) return ""; // System.out.println(cellValue.getCellType()); switch (cellValue.getCellType()) { case STRING: return cell.getStringCellValue(); case NUMERIC: // 获取数值并转为整型 double numericValue = cell.getNumericCellValue(); // 判断是否为整数 if (numericValue == (int)numericValue) { if((int)numericValue==0) return ""; else return String.valueOf((int)numericValue); } else { return String.valueOf(numericValue); // 或者根据需要返回四舍五入的整型 } case BOOLEAN: return String.valueOf(cell.getBooleanCellValue()); case FORMULA: return cell.getCellFormula()+""; case BLANK: return ""; default: return ""; } } private int getRealLastCellNum(Row row) { int lastCellNum = 0; for (int i = 0; i < row.getLastCellNum(); i++) { Cell cell = row.getCell(i); if (cell != null && cell.getCellType() != CellType.BLANK) { lastCellNum = i + 1; } } return lastCellNum; } // void generateSimpleExample() { // try { // // 1. 读取Excel文件 // String excelPath = RuoYiConfig.getProfile() + "/download/"+"卷內目录.xls"; // String pdfPath = RuoYiConfig.getProfile() + "/download/"+"1.pdf"; // // Workbook workbook = WorkbookFactory.create(new File(excelPath)); // FileOutputStream fos = new FileOutputStream(pdfPath); // FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); // // // // 获取第一个工作表 // Sheet sheet = workbook.getSheetAt(1); // // // 创建PDF文档对象 // Document document = new Document(PageSize.A2, 50, 50, 50, 50); // // // 创建PDF输出流 // PdfWriter writer = PdfWriter.getInstance(document, fos); // // 4. 处理工作表中的图片 // if (workbook instanceof XSSFWorkbook) { // handleXSSFImages((XSSFSheet)sheet, document); // } // // 打开PDF文档 // document.open(); // // // 创建PDF表格对象 // System.out.println(sheet.getRow(0).getLastCellNum()+"--00"); // PdfPTable table = new PdfPTable(sheet.getRow(0).getLastCellNum()); // table.setHeaderRows(1); // // // 设置表格宽度 // table.setWidthPercentage(100); // // // 设置表格标题 // Paragraph title = new Paragraph(sheet.getSheetName(), new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 16, Font.BOLD)); // title.setAlignment(Element.ALIGN_CENTER); // document.add(title); // // System.out.println(sheet.) // // 添加表格内容 // for (Row row : sheet) { // { // if (row == null) continue; // System.out.println(getRealLastCellNum(row)+"---987"); //// if(row.getRowNum()==0) //// continue; // if(row.getRowNum()==2) // { // PdfPCell pdfCell = ImageSet(100); // pdfCell.setColspan(7); // pdfCell.setRowspan(3); // pdfCell.setBorderWidth(1f); // pdfCell.setBorderColor(BaseColor.BLACK); // pdfCell.setPadding(5f); // pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER); // pdfCell.setVerticalAlignment(Element.ALIGN_MIDDLE); // table.addCell(pdfCell); // System.out.println("{{{{{{{{{{{{{"); // continue; // } // for (int i = 0; i < 7; i++) // { // // Cell cell = row.getCell(i); // if(row.getRowNum()==3) // { // PdfPCell pdfCell = new PdfPCell(new Paragraph("卷内目录", new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 12))); // pdfCell.setColspan(7); // pdfCell.setBorderWidth(1f); // pdfCell.setBorderColor(BaseColor.BLACK); // pdfCell.setPadding(5f); // pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER); // pdfCell.setVerticalAlignment(Element.ALIGN_MIDDLE); // table.addCell(pdfCell); // System.out.println("{{{{{{{{{{{{{"); // break; // } // if(cell==null) { // // table.addCell(""); // continue; // } // PdfPCell pdfCell = new PdfPCell(new Paragraph(getCellValue(cell, evaluator), new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 12))); // // if(row.getRowNum()!=1) { // pdfCell.setBorderWidth(1f); // pdfCell.setBorderColor(BaseColor.BLACK); // pdfCell.setPadding(5f); // pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER); // pdfCell.setVerticalAlignment(Element.ALIGN_MIDDLE); // } // if (cell.getRowIndex() == 5) { // pdfCell.setBackgroundColor(BaseColor.LIGHT_GRAY); // } // // table.addCell(pdfCell); // // } // } // } // // // 添加表格到PDF文档 // table.setSpacingBefore(20f); // table.setSpacingAfter(20f); // table.setKeepTogether(true); // document.add(table); // // // 关闭PDF文档 // document.close(); // // } catch (Exception e) { // e.printStackTrace(); // } } // 自定义页面事件类,用于在每个新页面添加卷内封面和卷号 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 dvss) throws DocumentException, IOException { Document document = new Document(); 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); // 获取卷号 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); // 添加表头 String[] headers = {"序号", "文件编号", "责任者", "文件题名", "日期", "页号", "备注"}; for (String header : headers) { PdfPCell cell = new PdfPCell(new Paragraph(header, chineseFont1)); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setBackgroundColor(new BaseColor(200, 200, 200)); table.addCell(cell); } // 添加表格数据 // Object[][] data = { // // {1, "商品A", 2, 100.00, 200.00}, // // {2, "商品B", 1, 250.50, 250.50}, // // {3, "商品C", 3, 80.00, 240.00} // }; // data. // for (Object[] row : data) { for (DocumentMaterialsVo cellData : dvss) { //序号 PdfPCell cell = new PdfPCell(new Paragraph(cellData.getNum().toString(), chineseFont)); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table.addCell(cell); //文件编号(档号) PdfPCell cell1 = new PdfPCell(new Paragraph(cellData.getDocumentNumber()==null?"":cellData.getDocumentNumber().toString(), new Font(bfChinese, 12))); cell1.setHorizontalAlignment(Element.ALIGN_CENTER); cell1.setVerticalAlignment(Element.ALIGN_MIDDLE); table.addCell(cell1); //序号 PdfPCell cell2 = new PdfPCell(new Paragraph(cellData.getCreator()==null?"":cellData.getCreator().toString(), chineseFont)); cell2.setHorizontalAlignment(Element.ALIGN_CENTER); cell2.setVerticalAlignment(Element.ALIGN_MIDDLE); table.addCell(cell2); //序号 PdfPCell cell3 = new PdfPCell(new Paragraph(cellData.getTitle()==null?"":cellData.getTitle().toString(), chineseFont)); cell3.setVerticalAlignment(Element.ALIGN_MIDDLE); cell3.setHorizontalAlignment(Element.ALIGN_CENTER); table.addCell(cell3); //序号 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // String dateString = sdf.format(date); PdfPCell cell4 = new PdfPCell(new Paragraph(cellData.getDate()==null?"":sdf.format(cellData.getDate()), chineseFont)); cell4.setVerticalAlignment(Element.ALIGN_MIDDLE); cell4.setHorizontalAlignment(Element.ALIGN_CENTER); table.addCell(cell4); //序号 PdfPCell cell5 = new PdfPCell(new Paragraph(cellData.getPageNumber()==null?"": cellData.getPageNumber().toString(), chineseFont)); cell5.setHorizontalAlignment(Element.ALIGN_CENTER); cell5.setVerticalAlignment(Element.ALIGN_MIDDLE); table.addCell(cell5); //序号 PdfPCell cell6 = new PdfPCell(new Paragraph(cellData.getRemarks()==null?"":cellData.getRemarks().toString(), chineseFont)); cell6.setVerticalAlignment(Element.ALIGN_MIDDLE); cell6.setHorizontalAlignment(Element.ALIGN_CENTER); table.addCell(cell6); } // } document.add(table); document.close(); } //设置备考表 public void generateFileStyleInfo(String pdfPath, String volumeNumber, Long id) throws IOException, DocumentException { Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream(pdfPath)); document.open(); // 创建PDF文档 List dmfs = documentMaterialsService.findFileStyleInfo(Math.toIntExact(id)); if(dmfs.isEmpty()) return; System.out.println(dmfs); PdfWriter.getInstance(document, new FileOutputStream("09-备考表"+".pdf")); document.open(); // 设置中文字体 BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font chineseFont = new Font(bfChinese, 16, Font.BOLD); // 添加标题 Paragraph title = new Paragraph("卷内备考表", chineseFont); title.setAlignment(Element.ALIGN_CENTER); document.add(title); // 添加内容 // String volumeNumber = "D3.4.1-05-2024-0002"; // 创建卷号段落,使用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(); int oth = dmfs.size()<=2?0: dmfs.get(2).getCnt(); int allCnt = dmfs.get(0).getCnt() + pcc + oth; document.add(new Paragraph(" 本 案 卷 共 有 文 件 材 料 " + allCnt + " 页"+",其中:文字材料 " + pcc + " 页"+",图样材料 " + oth + " 页"+",照片 " + dmfs.get(0).getCnt() + " 张", chineseFont)); document.add(new Paragraph("说明: ", chineseFont)); // 方法2:使用带换行符的Paragraph for(int i = 0; i < 10; i++) { Paragraph withNewLine = new Paragraph("\n"); document.add(withNewLine); } String tis1 = "立卷人:仇翀(广州盈家档案管理有限公司)"; Paragraph par1 = new Paragraph(tis1, chineseFont); par1.setAlignment(Element.ALIGN_RIGHT); document.add(par1); //拿到当前时间 // 获取当前日期 LocalDate currentDate = LocalDate.now(); // 打印年、月、日 // System.out.println("Year: " + currentDate.getYear()); // System.out.println("Month: " + currentDate.getMonthValue()); // 月份是从1开始的 // System.out.println("Day of Month: " + currentDate.getDayOfMonth()); Paragraph withNewLine = new Paragraph("\n"); document.add(withNewLine); String cdt = currentDate.getYear()+"年"+currentDate.getMonthValue()+"月"+currentDate.getDayOfMonth()+"日"; Paragraph par3 = new Paragraph(cdt, chineseFont); par3.setAlignment(Element.ALIGN_RIGHT); document.add(par3); String tis2 = "审核人:曾瑞莹(广州盈家档案管理有限公司)"; document.add(withNewLine); Paragraph par2 = new Paragraph(tis2, chineseFont); par2.setAlignment(Element.ALIGN_RIGHT); document.add(par2); document.add(withNewLine); document.add(par3); document.close(); } public void generatePdf(String pdfPath, Long id) throws IOException, DocumentException { Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream(pdfPath)); document.open(); String [] tits = {"档号:","档案馆(室)号:","缩微号:","发文号:", "案卷题名:","编制日期:","编制单位:","保管期限:","密级:"}; ArchiveRecords ard = iArchiveRecordsService.selectArchiveRecordsById(id); String formattedDate = ""; if(ard.getPreparationDate()!=null) { LocalDate date = ard.getPreparationDate().toInstant() .atZone(ZoneId.systemDefault()) .toLocalDate(); ; System.out.println("当前日期: " + date); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); formattedDate = date.format(formatter); } String [] cons = {ard.getRecordId(),ard.getArchiveRoomNumber(),ard.getMicrofilmNumber(),ard.getInquiryNumber(),ard.getCaseTitle(),formattedDate,ard.getPreparationUnit(), ard.getRetentionPeriod(),ard.getSecurityClassification()}; //把图片加入到pdf当中 Image img = Image.getInstance(createQrCodeN(cons[0], 80, 80)); // 设置图片在PDF中的位置(可选) // img.setAbsolutePosition(100, 100); // 将图片添加到PDF文档中 PdfPCell pdfPCell = new PdfPCell(img); pdfPCell.setBorder(Rectangle.NO_BORDER); // 移除单元格边框 pdfPCell.setMinimumHeight(80); 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 table = new PdfPTable(columnWidths); // PdfPTable table = new PdfPTable(2); table.setWidthPercentage(78); // 减小表格宽度百分比使两列更紧凑 table.setHorizontalAlignment(Element.ALIGN_LEFT); // 设置表格整体居中 table.setSpacingBefore(30f); // 设置表格前间距 table.setSpacingAfter(90f); // 设置表格后间距 // PdfPTable table1 = new PdfPTable(1); // table1.setWidthPercentage(90); // 增大表格宽度百分比 // table1.setHorizontalAlignment(Element.ALIGN_LEFT); // 设置表格整体居中 // table1.setSpacingBefore(10f); // 设置表格前间距 // table1.setSpacingAfter(10f); // 设置表格后间距 table.addCell(pdfPCell); // document.add(table1); // 设置中文字体 BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font chineseFont = new Font(bfChinese, 16, Font.BOLD); Font chineseFont1 = new Font(bfChinese, 10, Font.BOLD); // 添加档号 // 添加带下划线的档号 // 先计算所有标题的最长长度 int maxTitleLength = 0; for (String tit : tits) { maxTitleLength = Math.max(maxTitleLength, tit.length()-1); } for(int i = 0; i < tits.length; i++) { // 使用PdfPTable实现精确对齐 // 第一行:档号 // 实现对齐:在文字之间填充空格,使所有标题总长度相同 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)); // valueCell1.setBorder(Rectangle.NO_BORDER); labelCell1.setMinimumHeight(30); labelCell1.setPaddingTop(10f); // 上内边距10单位 labelCell1.setPaddingBottom(10f); // 下内边距10单位 labelCell1.setPaddingLeft(15f); // 左内边距15单位 labelCell1.setPaddingRight(0f); // 右内边距15单位 PdfPCell valueCell1 = new PdfPCell(new Phrase(cons[i], chineseFont)); valueCell1.setBorder(Rectangle.NO_BORDER); valueCell1.setUseBorderPadding(false); // 禁用边框内边距计算 valueCell1.setBorderWidthBottom(0.5f); // 设置底部边框作为下划线 valueCell1.setMinimumHeight(30); valueCell1.setPaddingTop(10f); // 上内边距10单位 valueCell1.setPaddingBottom(10f); // 下内边距10单位 valueCell1.setPaddingLeft(0f); // 左内边距0单位 valueCell1.setExtraParagraphSpace(0f); // 移除段落额外空间 valueCell1.setPaddingRight(15f); // 右内边距15单位 table.addCell(labelCell1); table.addCell(valueCell1); if(i==3) { //增加那个条形码 byte [] bas = barcodeService.generateBarcodeImage(cons[0]); Image img1= Image.getInstance(bas); PdfPCell pdfPCell1 = new PdfPCell(img1); pdfPCell1.setBorder(Rectangle.NO_BORDER); // 移除单元格边框 pdfPCell1.setMinimumHeight(20); pdfPCell1.setUseAscender(true); // 设置可以居中 pdfPCell1.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT); // 设置水平居中 pdfPCell1.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); // 设置垂直居中 pdfPCell1.setColspan(2); pdfPCell1.setPaddingBottom(20); pdfPCell1.setPaddingTop(20); table.addCell(pdfPCell1); } } document.add(table); // 空行 // 关闭文档 document.close(); } }