最近涉及到电子普通发票报销。就会涉及到上传以及打印发票的问题。
开发票肯定是大于两个PDF。分开打印浪费纸张。WPS的PDF合并转换的软件呢又需要会员。无奈。小帅丶就依靠自己三脚猫的能耐,用Java(Apche PDFBox)实现了一下PDF合并。
Apache PDFBox 是一个用于处理和操作 PDF 文件的开源 Java 库,它提供了丰富的功能和工具,用于创建、解析、操作和转换 PDF 文件。下面我们将介绍一下 Apache PDFBox 的优点、缺点以及类似的框架。
优点
强大的功能:Apache PDFBox 提供了丰富的功能和工具,包括创建、解析、操作、转换各种 PDF 文件。它可以用于生成 PDF 文档、提取文本内容、合并和拆分 PDF 文件等各种操作。
良好的文档支持:Apache PDFBox 配备了详尽的文档和示例,使开发人员可以快速上手并充分利用其功能。此外,它拥有一个活跃的开发者社区,用户可以从社区中获取支持和帮助。
跨平台兼容性:作为一个基于 Java 的库,Apache PDFBox 具有极强的跨平台兼容性,可以在各种操作系统和开发环境中使用。
缺点
学习曲线较陡峭:由于PDF文件的复杂性,Apache PDFBox 的使用可能需要一定的学习和实践。特别是对于处理 PDF 文件较为复杂的操作,可能需要一定的时间和精力。
相对较大的库:由于其强大的功能,Apache PDFBox 的库文件相对较大,可能占用一定的存储空间。
类似框架
iText:iText是另一个流行的用于处理PDF文件的Java库,提供了类似的功能和工具。与Apache PDFBox相比,iText可能在一些高级特性和商业化支持方面更加成熟。
PDFTron:PDFTron是一家专注于PDF技术的公司,提供了丰富的PDF处理解决方案和工具。它的SDK包括了丰富的功能和工具,能够满足各种PDF处理需求。
总的来说,Apache PDFBox 是一个强大而灵活的 Java 库,适用于各种处理和操作 PDF 文件的场景。选择使用 PDF 处理库时,需要结合具体的功能需求、文档支持以及各项性能指标来进行综合考量。
信息来源:百度搜素
1.PDF转图片,并进行缩放处理,DPI设定为300? ? ? ? ? ? ? ? ? ? ?
2.新建一个空白PDF(是提前创建好的哦~)? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
3.将第一步处理好的2个图片文件添加到空白PDF,设置透明度,缩放宽高比例符合A4大小,另存为PDF文件。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
大功告成!
温馨提示:需要额外字体支持~
/**
* @Author 小帅丶
* @Description 普通发票合并成一个PDF
* @Date 2022年12月27日09:58:59
* @param pdfParams - PDF数据
* @param isGray - 是否进行灰度处理图片
* @param grayType - 灰度类别
* @return java.io.ByteArrayOutputStream
**/
public static ByteArrayOutputStream mergeInvoiceOnePDF(List<PDFParams> pdfParams,
boolean isGray, Integer grayType) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
if(pdfParams.size()>2){
throw new Exception("PDF文件个数错误 最多不超过2个");
}else{
garyType(grayType);
//先对PDF进行处理
List<BufferedImage> allImg = new ArrayList<>();
long startTime = System.currentTimeMillis();
for (PDFParams pdfParam : pdfParams) {
PDFUtils.setFonts(FontFormat.TTF, "STSong-Light", FONT_FILE);
byte[] bytes = FileUtil.readBytes(pdfParam.getFilePath());
String pdfBase = Base64Encoder.encode(bytes);
List<BufferedImage> bufferedImages = PDFUtils.pdfToImage(pdfBase);
BufferedImage invoiceBI = bufferedImages.get(0);
if (isGray) {
invoiceBI = grayDealImage(invoiceBI, grayType);
}
allImg.add(invoiceBI);
}
System.out.println("PDF转图片耗时:" + (System.currentTimeMillis() - startTime));
//开始合并图片到PDF
if (!allImg.isEmpty()) {
//合成后的文件
PdfReader reader = new PdfReader(new FileInputStream(EMPTY_PDF));
PdfStamper stamper = new PdfStamper(reader, outputStream);
//将所有图片放在pdf文件的第1页
PdfContentByte over = stamper.getOverContent(1);
for (int i = 0; i < allImg.size(); i++) {
BufferedImage bufferedImage = allImg.get(i);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", outStream);
//图片转com.itextpdf.text.Image
com.itextpdf.text.Image contractSealImg = com.itextpdf.text.Image.getInstance(outStream.toByteArray());
over.saveState();
PdfGState pdfGState = new PdfGState();
//给图片设置透明度
pdfGState.setFillOpacity(1F);
over.setGState(pdfGState);
//缩放比例值
double scaleX = (double) DEFAULT_IMG_WIDTH / contractSealImg.getWidth();
//计算等比缩放的高度
float height = (float) (scaleX * contractSealImg.getHeight());
//设置图片位置
//PDF从底部左下角算为原点坐标
if (i == 0) {
contractSealImg.setAbsolutePosition(ABSOLUTE_X, ABSOLUTE_Y);
} else {
contractSealImg.setAbsolutePosition(ABSOLUTE_X, A4_72_HEIGHT - height);
}
//设置图片大小
contractSealImg.scaleAbsolute(DEFAULT_IMG_WIDTH, height);
//将图片添加到pdf文件
over.addImage(contractSealImg);
over.restoreState();
outStream.close();
}
stamper.setFormFlattening(true);
stamper.close();
reader.close();
outputStream.close();
}
System.out.println("合成总耗时:" + (System.currentTimeMillis() - startTime));
return outputStream;
}
}
小帅丶为了方便使用,将此功能实现发布在了微信小程序里面。搜索 小帅一点资讯
功能实现暂无涉及到商用内容,所以此功能呢,目前也是免费使用哦~
?也可以先看下视频操作。再进行体验哦~
温馨提示:理论上2张电子普通发票都可以合并哦?~