因为最近的业务需求设计pdf的解析,所以做了一些相关的学习。
首先是来自ChatGPT的回答:
要在Java中解析PDF,你可以使用Apache PDFBox库。PDFBox是一个流行的Java库,可以用来创建和解析PDF文件。以下是一个简单的示例,演示如何使用PDFBox解析PDF文件:
import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
public class PDFParser {
public static void main(String[] args) {
try {
// Load PDF document
File file = new File("example.pdf");
PDDocument document = PDDocument.load(file);
// Create PDFTextStripper
PDFTextStripper pdfStripper = new PDFTextStripper();
// Extract text from PDF
String text = pdfStripper.getText(document);
System.out.println("Extracted text:\n" + text);
// Close the document
document.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这个方案是可行的,它利用PDFTextStripper剥离器直接剥离pdf文件,也没有涉及page获取,也算简单方便,但是对于我司的业务而言,涉及的pdf出现了奇怪的问题,解析结果有pdf未显示的内容。可以理解为临近的两笔流水信息都打印出来了,但是pdf上只有其中一笔,我比较怀疑是上游在生成pdf的时候,基于了上一个流水的pdf编辑生成了下一个流水pdf。
而后使用了PDFTextStripperByArea这个剥离器,它是在PDF中指定区域解析文本
以下是ChatGPT的内容:
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripperByArea;
public class PDFParser {
public static void main(String[] args) {
try {
// Load PDF document
File file = new File("example.pdf");
PDDocument document = PDDocument.load(file);
// Define the area for text extraction (in points)
Rectangle rect = new Rectangle(100, 100, 200, 200); // x, y, width, height
// Create PDFTextStripperByArea
PDFTextStripperByArea pdfStripper = new PDFTextStripperByArea();
pdfStripper.addRegion("region", rect);
// Extract text from the specified area
pdfStripper.extractRegions(document.getPage(0));
String text = pdfStripper.getTextForRegion("region");
// Print extracted text
System.out.println("Extracted text from specified area:\n" + text);
// Close the document
document.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是其中有一个坑, pdfStripper.addRegion("region", rect) 这一句,我在2.0.31版本或者更高3的版本都是不能用Rectangle的
Modifier and Type | Method and Description |
void | addRegion(String regionName, Rectangle2D rect) Add a new region to group text by. |
上面的内容来自官方接口文档
那查阅了一些文章之后改为以下使用方式:
// 新建一个矩形,参数依次为:左上角坐标x, y, 宽width, 高height
Rectangle2D rect = new Rectangle2D.Double(100, 100, 200, 200);
PDFTextStripperByArea pdfStripper = new PDFTextStripperByArea();
pdfStripper.addRegion("region", rect);
pdfStripper.extractRegions(document.getPage(0));
String text = pdfStripper.getTextForRegion("region");
期间还有参考了一篇文章,它的page获取方式是从文档树获取的,我试了一下不行,会报空指针,需要像上面这样直接从document获取。
而坐标的获取可以参考这篇文章:如何获取PDF文件中对应内容的坐标及范围?_pdf坐标-CSDN博客
开启坐标显示:
坐标显示单位切换
对于PDFbox来说它需要的坐标单位是点,而不是厘米,因此还需要对其显示的值进行设置。打开首选项:
将显示单位切换成“点”
开启网格辅助线
网格开启方便观察位置横竖位置
测量工具使用
按住shift键会锁定横竖对齐,测量更准确