二维码
This commit is contained in:
@ -219,16 +219,11 @@ public class PdfBoxQrCodeGenerator {
|
||||
|
||||
|
||||
|
||||
// 固定的边距(点)
|
||||
private static final float MARGIN = 10.0f;
|
||||
// 二维码大小比例(页面宽高中较小值的20%)
|
||||
private static final float QR_SIZE_RATIO = 0.2f;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 在PDF每一页的指定位置添加二维码并返回数据流(二维码放大10倍,居中放置,带边界检查)
|
||||
*/
|
||||
public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
|
||||
throws IOException {
|
||||
|
||||
@ -263,50 +258,37 @@ public class PdfBoxQrCodeGenerator {
|
||||
for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
|
||||
PdfPage page = pdfDoc.getPage(pageNum);
|
||||
|
||||
// 获取页面的实际可见区域(裁剪框)
|
||||
// 获取页面的所有边界框信息
|
||||
Rectangle mediaBox = page.getMediaBox();
|
||||
Rectangle cropBox = page.getCropBox();
|
||||
if (cropBox == null) {
|
||||
cropBox = page.getPageSize();
|
||||
}
|
||||
|
||||
float pageWidth = cropBox.getWidth();
|
||||
float pageHeight = cropBox.getHeight();
|
||||
// 使用CropBox作为主要参考,因为它定义了页面的可见区域
|
||||
Rectangle visibleArea = (cropBox != null) ? cropBox : mediaBox;
|
||||
|
||||
// 计算页面宽高中较小的值
|
||||
float minDimension = Math.min(visibleArea.getWidth(), visibleArea.getHeight());
|
||||
|
||||
// 动态计算二维码大小(页面宽高中较小值的20%)
|
||||
float qrSize = minDimension * QR_SIZE_RATIO;
|
||||
|
||||
// 输出页面尺寸信息
|
||||
System.out.println("页面 " + pageNum + " 宽度: " + pageWidth + ", 高度: " + pageHeight);
|
||||
System.out.println("页面 " + pageNum + " 尺寸: " + visibleArea.getWidth() + "x" + visibleArea.getHeight());
|
||||
System.out.println("页面 " + pageNum + " 二维码大小 (点): " + qrSize);
|
||||
|
||||
// 根据页面大小动态计算二维码尺寸(页面宽度的15%)
|
||||
float qrSize = pageWidth * 0.15f;
|
||||
// 计算左上角的位置(PDF坐标系:原点在左下角)
|
||||
float qrX = visibleArea.getLeft() + MARGIN;
|
||||
float qrY = visibleArea.getTop() - qrSize - MARGIN;
|
||||
|
||||
// 设置边距(页面宽度的2%)
|
||||
float margin = pageWidth * 0.02f;
|
||||
|
||||
// 计算二维码位置 - 左上角
|
||||
// 注意:PDF坐标系的原点在左下角,所以Y坐标需要从页面高度减去二维码高度和边距
|
||||
float qrX = cropBox.getLeft() + margin;
|
||||
float qrY = cropBox.getTop() - qrSize - margin;
|
||||
// 打印二维码位置信息
|
||||
System.out.println("页面 " + pageNum + " 左上角二维码位置: x=" + qrX + ", y=" + qrY);
|
||||
|
||||
try {
|
||||
// 使用最简单的方法:直接添加图像
|
||||
addQRCodeSimple(pdfDoc, page, qrCodeBytes, qrX, qrY, qrSize);
|
||||
// 使用Canvas API添加左上角二维码
|
||||
addQRCodeWithCanvas(pdfDoc, page, qrCodeBytes, qrX, qrY, qrSize);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("在页面 " + pageNum + " 添加二维码时出错: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
|
||||
// 尝试使用Canvas方法作为备用
|
||||
try {
|
||||
addQRCodeWithCanvas(pdfDoc, page, qrCodeBytes, qrX, qrY, qrSize, cropBox);
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Canvas备用方法也失败: " + ex.getMessage());
|
||||
|
||||
// 最后尝试使用原始大小
|
||||
try {
|
||||
addQRCodeSimple(pdfDoc, page, qrCodeBytes, qrX, qrY, 50); // 使用固定大小
|
||||
} catch (Exception ex2) {
|
||||
System.err.println("最简单方法也失败: " + ex2.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,89 +296,44 @@ public class PdfBoxQrCodeGenerator {
|
||||
return pdfOut;
|
||||
}
|
||||
|
||||
// 使用Canvas的备用方法
|
||||
// 使用Canvas API添加图像
|
||||
private static void addQRCodeWithCanvas(PdfDocument pdfDoc, PdfPage page,
|
||||
byte[] qrCodeBytes, float x, float y, float size, Rectangle pageSize) throws IOException {
|
||||
|
||||
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
|
||||
try (Canvas canvas = new Canvas(pdfCanvas, pageSize)) {
|
||||
ImageData imageData = ImageDataFactory.create(qrCodeBytes);
|
||||
com.itextpdf.layout.element.Image image = new com.itextpdf.layout.element.Image(imageData);
|
||||
|
||||
// 设置二维码尺寸和位置
|
||||
image.scaleAbsolute(size, size);
|
||||
image.setFixedPosition(x, y);
|
||||
|
||||
// 设置透明度确保不会被背景遮挡
|
||||
image.setOpacity(0.9f);
|
||||
|
||||
canvas.add(image);
|
||||
}
|
||||
}
|
||||
|
||||
// 最简单的方法:使用原始图像大小
|
||||
private static void addQRCodeSimple(PdfDocument pdfDoc, PdfPage page,
|
||||
byte[] qrCodeBytes, float x, float y, float size) throws IOException {
|
||||
|
||||
PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
|
||||
// 创建Canvas对象 - 使用PdfPage和Rectangle构造函数
|
||||
Canvas canvas = new Canvas(page, page.getPageSize());
|
||||
|
||||
// 创建图像对象
|
||||
// 创建图像数据
|
||||
ImageData imageData = ImageDataFactory.create(qrCodeBytes);
|
||||
com.itextpdf.kernel.pdf.xobject.PdfImageXObject imageXObject =
|
||||
new com.itextpdf.kernel.pdf.xobject.PdfImageXObject(imageData);
|
||||
|
||||
// 添加图像到指定位置(使用原始大小)
|
||||
canvas.addXObjectAt(imageXObject, x, y);
|
||||
// 创建Image对象
|
||||
Image image = new Image(imageData);
|
||||
|
||||
canvas.release();
|
||||
// 设置图像位置和大小
|
||||
image.setFixedPosition(x, y);
|
||||
image.setWidth(size);
|
||||
image.setHeight(size);
|
||||
|
||||
// 添加图像到Canvas
|
||||
canvas.add(image);
|
||||
|
||||
// 关闭Canvas
|
||||
canvas.close();
|
||||
|
||||
System.out.println("Canvas方法设置位置: x=" + x + ", y=" + y);
|
||||
}
|
||||
|
||||
public static void simpleTest(String pdfPath, String outputPath, byte[] qrCodeBytes) {
|
||||
try {
|
||||
PdfDocument pdfDoc = new PdfDocument(new PdfReader(pdfPath), new PdfWriter(outputPath));
|
||||
|
||||
for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
|
||||
PdfPage page = pdfDoc.getPage(i);
|
||||
Rectangle rect = page.getPageSize();
|
||||
|
||||
// 简单地在左上角添加一个固定大小的二维码
|
||||
PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
|
||||
|
||||
ImageData imageData = ImageDataFactory.create(qrCodeBytes);
|
||||
com.itextpdf.kernel.pdf.xobject.PdfImageXObject imageXObject =
|
||||
new com.itextpdf.kernel.pdf.xobject.PdfImageXObject(imageData);
|
||||
|
||||
// 固定位置和大小
|
||||
float x = 20; // 固定X位置
|
||||
float y = rect.getHeight() - 70; // 固定Y位置
|
||||
|
||||
canvas.addXObjectAt(imageXObject, x, y);
|
||||
canvas.release();
|
||||
}
|
||||
|
||||
pdfDoc.close();
|
||||
System.out.println("简单测试完成");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// String path = "C:\\Users\\YuanJie\\Desktop\\test.pdf";
|
||||
// String outputPath = "C:\\Users\\YuanJie\\Desktop\\test1.pdf";
|
||||
// String params = "http://192.168.110.151:7788/codeDetail?id=" + "1957649652924448769";
|
||||
// byte[] bytes = PdfBoxQrCodeGenerator.generateQRCodeBytes(params);
|
||||
// simpleTest(path, outputPath, bytes);
|
||||
// }
|
||||
|
||||
// 如果使用带放大倍数参数的方法,需要修改main方法:
|
||||
// main方法示例
|
||||
public static void main(String[] args) {
|
||||
//合规性手续业务流 test 测试101_101
|
||||
String path = "C:\\Users\\YuanJie\\Desktop\\合规性手续业务流.pdf";
|
||||
|
||||
String path = "C:\\Users\\YuanJie\\Desktop\\test.pdf";
|
||||
String outputPath = "C:\\Users\\YuanJie\\Desktop\\test1.pdf";
|
||||
|
||||
String params = "http://192.168.110.151:7788/codeDetail?id=" + "1957649652924448769";
|
||||
byte[] bytes = PdfBoxQrCodeGenerator.generateQRCodeBytes(params);
|
||||
BufferedImage image = QrCodeUtil.generate(params, 200, 200);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ImgUtil.write(image, ImgUtil.IMAGE_TYPE_PNG, out);
|
||||
byte[] bytes = out.toByteArray();
|
||||
|
||||
try {
|
||||
System.out.println("二维码字节大小: " + bytes.length + " 字节");
|
||||
@ -407,9 +344,8 @@ public class PdfBoxQrCodeGenerator {
|
||||
System.out.println("二维码图片已保存到桌面,用于验证二维码是否生成正确");
|
||||
}
|
||||
|
||||
// 在每一页添加二维码,放大10倍
|
||||
ByteArrayOutputStream byteArrayOutputStream =
|
||||
PdfBoxQrCodeGenerator.addQRCodeToPDFOnAllPages(path, bytes, false);
|
||||
// 在每一页添加二维码
|
||||
ByteArrayOutputStream byteArrayOutputStream = addQRCodeToPDFOnAllPages(path, bytes, false);
|
||||
|
||||
try (FileOutputStream fileOut = new FileOutputStream(outputPath)) {
|
||||
byteArrayOutputStream.writeTo(fileOut);
|
||||
@ -447,6 +383,12 @@ public class PdfBoxQrCodeGenerator {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user