在数字文档处理领域,PDF和HTML是两种非常流行的格式。PDF以其跨平台的可移植性和版式保持性而受到青睐,而HTML则是构建网页内容的标准。在许多应用场景中,我们需要将PDF文件转换为HTML格式,以便于在网页上展示或进一步处理。最近我接收到一个需求就是将PDF的内容转换成HTML然后展示到表单上,其中PDF包含表格。经过一顿操作,终于解决了,现将方法写出来,供大家参考。
PDF和HTML的基础: PDF是一种广泛使用的文件格式,它能够保持文件的原始布局、图像和文本格式。HTML是构建网页内容的标准语言,它使用标签来定义内容的结构和样式。PDF与HTML的主要区别在于,PDF是用于文档交换的格式,而HTML是用于网页显示的格式。
Java处理PDF的库: Apache PDFBox是一个开源工具,用于处理PDF文档。它提供了广泛的API来创建、渲染、打印和编辑PDF文档。iText是一个商业库,它提供了类似的功能,但在处理复杂PDF时可能更加高效。PDFRenderer是另一个库,专门用于从PDF文件中提取文本。
PDF解析技术概述: PDF文件由一系列对象组成,包括文本、图像、矢量图形和字体。使用Java库,我们可以解析这些对象并提取所需的信息。文本提取是转换过程中的关键步骤,它涉及到识别PDF中的文本元素并将其转换为HTML格式。
转换流程: 转换流程通常包括以下步骤:解析PDF文件、提取文本和图像、处理表格和布局、生成HTML代码。在这个过程中,我们需要特别注意保持原始PDF的格式和布局。
实现步骤: 如果你的文档完全是文本且没有复杂的格式,完全可以直接使用如下方式读取文本,然后根据文本自己重写样式:
但是奈何需求没有那么简单,我的PDF是包含表格,且表格里的内容有残次不齐竖着的文本,而且还要去除首页内容,所以我这次用的方式是现将PDF截取首页后重新生成PDF,然后再转换成HTML。具体实现方式代码如下:
1、引入以下依赖
<dependency>
<groupId>net.sf.cssbox</groupId>
<artifactId>pdf2dom</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>net.mabboud.fontverter</groupId>
<artifactId>FontVerter</artifactId>
<version>1.2.22</version> <!-- 请根据需要使用最新版本 -->
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version> <!-- 请根据需要使用最新版本 -->
</dependency>
<!--pdf转文本-->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.24</version>
</dependency>
2、实现关键代码
File file = new File(pdfUrl);
String localPdfFilePath = 要解析的PDF文件路径(本地)+ file.getName();
String newPdfFilePath = 截取PDF后生成的PDF文件路径+ file.getName();
String outFilePath = 生成的HTML文件.html";
String pdfContent = "";
PDDocument pdfDocument = PDDocument.load(new File(localPdfFilePath));
// 检查文档中是否有页面
if (pdfDocument.getNumberOfPages() > 0) {
// 移除第一页
pdfDocument.removePage(0);
}
// 保存更改后的PDF到新文件
pdfDocument.save(new File(newPdfFilePath));
System.out.println("第一页已被移除,新PDF保存在: " + newPdfFilePath);
pdfDocument.close();
// 转换成html格式文件
PDDocument document = PDDocument.load(new File(newPdfFilePath));
Writer writer = new PrintWriter(outFilePath, "UTF-8");
new PDFDomTree().writeText(document, writer);
writer.close();
document.close();
// 获取html内容
try (BufferedReader reader = new BufferedReader(new FileReader(outFilePath))) {
StringBuilder htmlContent = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
htmlContent.append(line).append("\n"); // 追加每一行内容,并添加换行符
}
pdfContent = String.valueOf(htmlContent);
} catch (IOException e) {
e.printStackTrace();
System.err.println("读取 HTML 文件时出错。");
}
性能考量: 在处理大型PDF文件时,性能是一个重要的考量因素。我们将讨论一些提高转换效率的技巧,例如并行处理和缓存。性能这个必须要注意,比如文件页数和数量。比如我这次的文件页数仅在10页以内,但是数量有20万,所以我采用的是多线程解析。还有一个要注意的是解析出来的HTML文本很大,因为文件页数和转换成HTML后会额外加一些代码,导致解析出来的文本内容大,达到了一个文本内容1M,所以这次解析出来的文本内容在单表存储,通过ID跟业务表关联。
由于网上也有大量解析方法,但是适合自己的才是最好的,这里重点讲一个踩坑的,开始我通过com.spire.pdf.PdfDocument/3.9.0方式在本地解析成功了,但是发布到测试环境却解析报错,估计是版本低导致被发现了,后面通过升级版本后不报错了,但是因为包含表格又只能解析前面三页或者除了表格的那两页,其他都能解析出来。 这个是坑之一,做需求一定要发版到环境上才能算成功。
最终经过各种版本测试才发现了这次的方法,即用org.fit.pdfdom.PDFDomTree方式。里面的各种版本大家在使用的时候试多几个就知道了,好了,本次记录到此结束。