java 对PDF的操作(生成,转换,转图片,转base64等)

简介: java 对PDF的操作(生成,转换,转图片,转base64等)

1、Pdf创建修改

公众号有一个用户在线签名生成合同的功能。当时将用户信息自动填充到合同中,以及用户签名填充到合同中,就有用到这些东西,只是那个时候没有进行总结,这次因为之前生成的合同一直都不具备有法律效率,所以要重新进行开发,依赖第三方具有法律认证的公司,并且添加了盖章的功能。

首先之前自己的写法,往pdf模板中填充内容。创建pdf的模板,用软件Acrobat,选择工具----》准备表单------》选择需要生成的pdf然后创建输入框,并且给每个需要填充的输入框起一个名字。注意这里需要指定字体的类型,否则最后生成的pdf字体不一样。模板准备好后,开始进行代码的开发。

依赖包:

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency><!--字体集--><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency>

操作代码:

importjava.io.ByteArrayOutputStream;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.StringReader;
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.Map;
importorg.apache.commons.codec.binary.Base64;
importorg.eclipse.jdt.internal.compiler.batch.Main;
importcom.itextpdf.text.Image;
importcom.itextpdf.text.Rectangle;
importcom.itextpdf.text.log.SysoCounter;
importcom.itextpdf.text.pdf.AcroFields;
importcom.itextpdf.text.pdf.BaseFont;
importcom.itextpdf.text.pdf.PdfContentByte;
importcom.itextpdf.text.pdf.PdfReader;
importcom.itextpdf.text.pdf.PdfStamper;
importcom.tl.weixin.GlobalVar;
importepm.core.webservice.sgcscws.CommonDataServiceProxy;
/**** 娴嬭瘯  鍏ュ弬map鐢熸垚* @author MJX**/publicclassPdfMakeTest {
// 入参传的一个是 key value 形式的 map 填充的文字内容// 另一个传输的是 签字图片转成的 byte数组//生成 base64 pdf  过户 更改publicStringsendpdfGh(Map<String, String>content, byte[] imgb) {
StringstrBase64=null;
try {
StringfieldName="contractQz";
// filePath 是 模板的路径信息 可以注意下面 被转换成了reader 所以不是具体的位置也可以,可以转成其他的方式 存储最后转成 reader的形式就行StringfilePath=this.getClass().getClassLoader().getResource("/").getPath();
//System.out.println(filePath);//                String filePath = "D:\\jmgh.pdf";//PdfReader reader = new PdfReader(new FileInputStream(new  File(filePath)));filePath=filePath+content.get("pdfVersion");
PdfReaderreader=newPdfReader(filePath);
// 输出流 是为了接 转换的pdf 模板ByteArrayOutputStreambos=newByteArrayOutputStream();
PdfStamperpsf=newPdfStamper(reader, bos);
PdfContentByteunder=psf.getUnderContent(1);
// 创建字体BaseFontbf=BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
ArrayListfontList=newArrayList();
fontList.add(bf);
AcroFieldsfields=psf.getAcroFields();
// 设置生成时候的字体fields.setSubstitutionFonts(fontList);
// 循环 key  value 根据key  查找模板中的隐藏域 然后将value填充for (Stringkey : content.keySet()) {
Stringvalue= (String) content.get(key);
fields.setField(key, value);
                }
// fields.setField("USER_NO", cons_no);// fields.setField("BASE_TYPE4", "false");// fillData(fields, data(cusdeal));// 以下 是改良的 填充 签名 信息// 因为签名是一个 图片 直接填充的时候 会 有位置不对应的问题// 怀疑是 上面的 PdfContentByte under = psf.getUnderContent(1); 参数获取的是1 的问题// 获取表单中的 所有 隐藏域名字AcroFieldsform=psf.getAcroFields();
//获取 关键字在第几页的 页数intpageNo=form.getFieldPositions(fieldName).get(0).page;
// 根据 关键字 获取 签名区域 并定位到 位置的 坐标RectanglesignRect= ((AcroFields.FieldPosition) fields.getFieldPositions(fieldName).get(0)).position;
floatx=signRect.getLeft();
floaty=signRect.getBottom();
Imageimage=null;
// image = Image.getInstance(signature_url + "/" + cons_no + ".png");// 获取 image  的图片对象image=Image.getInstance(imgb);
//设置第几页的添加PdfContentByteunder2=psf.getOverContent(pageNo);
// 依据 模板中的 长宽 设置 图片的长宽image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// 设置图片的坐标 并且 under2 添加图片image.setAbsolutePosition(x, y);
under2.addImage(image);
//  完结psf.setFormFlattening(true);
psf.close();
// 因为 上面 将pdf写入到了输出流中 相当于一直在操作流// 所以 这里可以直接将流 进行转换 base64 返回 也可以 转成 本地的 图片  直接操作 bos 输出流就可以strBase64=Base64.encodeBase64String(bos.toByteArray());
//    System.out.println(strBase64);bos.close();
            } catch (Exceptione) {
e.printStackTrace();
            } finally {
            }
returnstrBase64;
//return rtncode + "," + rtnMsg;        }
}

以上就是依据模板生成的 pdf,并且是base64形式的可进行传输当然,模板传入也可以动态的传入以上代码可以进行提取,动态可变参数全部提出来。

附带一个转换类,将生成好的base64 转换成pdf文档,验证是否正确。

importjava.io.BufferedInputStream;
importjava.io.BufferedOutputStream;
importjava.io.ByteArrayInputStream;
importjava.io.File;
importjava.io.FileOutputStream;
importsun.misc.BASE64Decoder;
publicclassBaseToPdf {
/*** Description: 将base64编码内容转换为Pdf* @param  base64编码内容,文件的存储路径(含文件名)* @Author MJX* Create Date: 2029年7月30日 */publicstaticvoidbase64StringToPdf(Stringbase64Content,StringfilePath){
BASE64Decoderdecoder=newBASE64Decoder();
BufferedInputStreambis=null;
FileOutputStreamfos=null;
BufferedOutputStreambos=null;
try {
byte[] bytes=decoder.decodeBuffer(base64Content);//base64编码内容转换为字节数组ByteArrayInputStreambyteInputStream=newByteArrayInputStream(bytes);
bis=newBufferedInputStream(byteInputStream);
Filefile=newFile(filePath);
Filepath=file.getParentFile();
if(!path.exists()){
path.mkdirs();
            }
fos=newFileOutputStream(file);
bos=newBufferedOutputStream(fos);
byte[] buffer=newbyte[1024];
intlength=bis.read(buffer);
while(length!=-1){
bos.write(buffer, 0, length);
length=bis.read(buffer);
            }
bos.flush();
        } catch (Exceptione) {
e.printStackTrace();
        }finally{
//closeStream(bis, fos, bos);        }
    }
publicstaticvoidmain(String[] args) {
Stringkk="";
base64StringToPdf(kk,"E:\\cn25.pdf");
    }
}

2、PDF转图片

pdf的转图片的原因是展示用。直接给用户展示pdf PC端和安卓(安卓有的可以用,有的可以下载)直接用a标签然后跟pdf的路径就可以,但是在IOS上 没有办法。== 坑了因为做的是移动端的还必须各种兼容。前台使用pdfjs进行渲染,发现小的pdf文档还可以接受,但是大一点的就GG 了。渲染的时间太长,好久都加载不出来。而且没有经过填充的快,但是填充过的pdf文档加载很慢。所以想到了 将pdf 转换成图片的方式,前台拿到图片的数组,然后一张一张的展示图片的base64 这样浏览器直接渲染,速度会大幅度的提升。第三方厂家提供了 pdf 转图片的功能,不知道是传输过程的问题,还是厂家转换的问题。速度太慢。自己百度了一套。pdfbox 阿帕奇的工具,依赖windows的字体库,linux需要自己装字体。

依赖:

<!--pdf压缩信息begin--><dependency><groupId>org.apache.pdfbox</groupId><artifactId>fontbox</artifactId><version>2.0.9</version></dependency><!--https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox --><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.9</version></dependency><!--https://mvnrepository.com/artifact/commons-logging/commons-logging --><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><!--pdf压缩信息end-->
importorg.apache.pdfbox.pdmodel.PDDocument;
importorg.apache.pdfbox.rendering.PDFRenderer;
importjavax.imageio.ImageIO;
importjava.awt.image.BufferedImage;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.util.ArrayList;
importjava.util.Base64;
importjava.util.List;
/*** ChangePdfOne** @author MJX* @date 2020/5/6*/publicclassChangePdfOne {
/*** 转换全部的pdf* @param type 图片类型pdfStr:pdf的base64type 是图片类型*/publicstaticListpdf2png(StringpdfStr, Stringtype) {
// 将pdf装图片 并且自定义图片得格式大小//        File file = new File(fileAddress+"\\"+filename+".pdf");byte[] decode=Base64.getDecoder().decode(pdfStr);
try {
PDDocumentdoc=PDDocument.load(decode);
//            PDDocument doc = PDDocument.load(file);PDFRendererrenderer=newPDFRenderer(doc);
intpageCount=doc.getNumberOfPages();
ArrayList<String>list=newArrayList<>();
for (inti=0; i<pageCount; i++) {
// 控制清晰度 后面的100 值越大越清晰 BufferedImageimage=renderer.renderImageWithDPI(i, 100); // Windows native DPI// BufferedImage srcImage = resize(image, 240, 240);//产生缩略图//                ImageIO.write(image, type, new File(fileAddress+"\\"+filename+"_"+(i+1)+"."+type));ByteArrayOutputStreambos=newByteArrayOutputStream();
ImageIO.write(image,type,bos);
byte[] bytes=bos.toByteArray();
Stringbase=Base64.getEncoder().encodeToString(bytes);
list.add(base);
//                System.out.println("base = " + base);//                File file = new File("D:\\testAnySignEncPackage\\"+ i +"."+"jpg");//                FileUtils.writeByteArrayToFile(file, bytes);            }
returnlist;
        } catch (IOExceptione) {
e.printStackTrace();
        }
returnnull;
    }
publicstaticvoidmain(String[] args) {
pdf2png("","jpg");
    }
}

生成的图片有乱码的情况,百度发现大多说的都是字体不完全,需要安装字体库。找了好久 最终也没有找到 mstmc.ttf的字体在哪里安装==。


目录
相关文章
|
Java
Java开发实现图片URL地址检验,如何编码?
【10月更文挑战第14天】Java开发实现图片URL地址检验,如何编码?
432 4
|
4月前
|
XML 人工智能 Java
java实现PDF 电子签章
本文介绍了使用Java将Word文档转换为PDF并添加水印、签名和盖章的方法。通过Apache POI读取Word内容,结合OpenPDF生成PDF文件,并利用PdfPageEvent接口实现页面水印与签名功能。代码示例清晰展示了转换流程及关键实现细节。
258 0
|
自然语言处理 数据可视化 Java
iText 全面介绍:强大的 Java PDF 操作库
iText是强大的Java PDF库,支持创建、读取、加密、签名、水印、合并拆分等操作。广泛用于报表生成、电子签章、合同发票等场景。支持中文及多语言,推荐使用模块化、高性能的iText 7版本,适用于企业级PDF处理需求。
280 0
|
2月前
|
机器学习/深度学习 文字识别 Java
Python实现PDF图片OCR识别:从原理到实战的全流程解析
本文详解2025年Python实现扫描PDF文本提取的四大OCR方案(Tesseract、EasyOCR、PaddleOCR、OCRmyPDF),涵盖环境配置、图像预处理、核心识别与性能优化,结合财务票据、古籍数字化等实战场景,助力高效构建自动化文档处理系统。
517 0
|
6月前
|
人工智能 搜索推荐 算法
PDF 转 JPG 图片小工具:CodeBuddy 助力解决转换痛点
在 PDF 转 JPG 的实际应用中,用户普遍面临转换质量差、批量处理效率低、格式兼容性不足以及编程实现困难等痛点。而 CodeBuddy 凭借智能代码生成与优化、实时错误诊断修复、助力代码学习拓展,以及支持多场景适配与个性化定制等强大的 AI 编程能力,精准直击这些难题。使用 CodeBuddy 开发 Python PDF 转 JPG 小工具,能够有效提升转换效率与质量,降低开发门槛和成本,为用户带来高效、优质的文件格式转换体验。
203 16
|
5月前
|
存储 Java 数据安全/隐私保护
Java技术栈揭秘:Base64加密和解密文件的实战案例
以上就是我们今天关于Java实现Base64编码和解码的实战案例介绍。希望能对你有所帮助。还有更多知识等待你去探索和学习,让我们一同努力,继续前行!
437 5
|
5月前
|
存储 安全 算法
Java 集合面试题 PDF 下载及高频考点解析
本文围绕Java集合面试题展开,详细解析了集合框架的基本概念、常见集合类的特点与应用场景。内容涵盖`ArrayList`与`LinkedList`的区别、`HashSet`与`TreeSet`的对比、`HashMap`与`ConcurrentHashMap`的线程安全性分析等。通过技术方案与应用实例,帮助读者深入理解集合类的特性和使用场景,提升解决实际开发问题的能力。文末附带资源链接,供进一步学习参考。
127 4
|
5月前
|
人工智能 开发工具 开发者
【HarmonyOS 5】鸿蒙应用实现发票扫描、文档扫描输出PDF图片或者表格的功能
HarmonyOS 系统提供的核心场景化视觉服务,旨在帮助开发者快速实现移动端文档数字化功能。
216 0
|
7月前
|
前端开发 JavaScript Java
Java中将图片转换为base64格式的技巧
这样,你就可以在Java中将图片转换为Base64格式了。这个方法的实现非常简单,只需要使用Java的内置库,无需任何额外的库。希望这个方法对你有所帮助。
426 22
|
Java
Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
【10月更文挑战第14天】Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
262 2