| | |
| | | |
| | | @Autowired |
| | | private IArchiveRecordsService iArchiveRecordsService; |
| | | private static BufferedImage trimWhiteBorder(BufferedImage img) { |
| | | int width = img.getWidth(); |
| | | int height = img.getHeight(); |
| | | |
| | | int minX = width, minY = height, maxX = 0, maxY = 0; |
| | | |
| | | // 查找非白色像素的边界 |
| | | for (int y = 0; y < height; y++) { |
| | | for (int x = 0; x < width; x++) { |
| | | int rgb = img.getRGB(x, y); |
| | | // 如果不是白色 |
| | | if ((rgb & 0x00FFFFFF) != 0x00FFFFFF) { |
| | | if (x < minX) minX = x; |
| | | if (x > maxX) maxX = x; |
| | | if (y < minY) minY = y; |
| | | if (y > maxY) maxY = y; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 如果全是白色,返回原图 |
| | | if (minX > maxX || minY > maxY) { |
| | | return img; |
| | | } |
| | | |
| | | // 裁剪 |
| | | int newWidth = maxX - minX + 1; |
| | | int newHeight = maxY - minY + 1; |
| | | |
| | | // 添加1像素安全边距(可选) |
| | | minX = Math.max(0, minX - 1); |
| | | minY = Math.max(0, minY - 1); |
| | | newWidth = Math.min(width - minX, newWidth + 2); |
| | | newHeight = Math.min(height - minY, newHeight + 2); |
| | | |
| | | return img.getSubimage(minX, minY, newWidth, newHeight); |
| | | } |
| | | //生产二维码 |
| | | public byte[] createQrCodeN(String content, int width, int height) throws IOException { |
| | | QrConfig config = new QrConfig(width, height); |
| | | |
| | | config.setMargin(3); |
| | | config.setMargin(2); |
| | | // 高纠错级别 |
| | | config.setErrorCorrection(ErrorCorrectionLevel.H); |
| | | // 设置前景色,既二维码颜色(自行选择颜色修改) |
| | | config.setForeColor(new Color(11, 11, 11).getRGB()); |
| | | // 设置背景色(灰色)需要背景色时候打开链接 |
| | | config.setBackColor(new Color(242,242,242).getRGB()); |
| | | config.setForeColor(java.awt.Color.BLACK); |
| | | config.setBackColor(java.awt.Color.WHITE); |
| | | |
| | | |
| | | BufferedImage bufferedImage = QrCodeUtil.generate(// |
| | | content, //二维码内容 |
| | | config |
| | | ); |
| | | |
| | | // 步骤2:手动裁剪白边 |
| | | bufferedImage = trimWhiteBorder(bufferedImage); |
| | | System.out.println(bufferedImage); |
| | | System.out.println("---02340230949394"); |
| | | ByteArrayOutputStream os = new ByteArrayOutputStream(); |
| | |
| | | } |
| | | |
| | | |
| | | // 自定义页面事件类,用于在每个新页面添加卷内封面内容 |
| | | // 自定义页面事件类,用于在每个新页面添加卷内封面和卷号 |
| | | 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(); |
| | |
| | | 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); |
| | | |
| | |
| | | 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); |
| | | |
| | |
| | | |
| | | // 添加内容 |
| | | // 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(); |