Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >itext7知识点研究(PDF编辑)

itext7知识点研究(PDF编辑)

作者头像
老梁
发布于 2019-09-10 09:33:04
发布于 2019-09-10 09:33:04
2.8K00
代码可运行
举报
运行总次数:0
代码可运行

取出pdf文档文字

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String sourceFolder2 = "E:\\picture2\\租赁合同2.pdf";
PdfDocument doc = new PdfDocument(new PdfReader(sourceFolder2));
float height = doc.getPage(1).getPageSize().getHeight();
float width = doc.getPage(1).getPageSize().getWidth();
Rectangle rect = new Rectangle(width,height);
FilteredTextEventListener filterListener = new FilteredTextEventListener(new LocationTextExtractionStrategy(), new TextRegionEventFilter(rect));
String extractedText = PdfTextExtractor.getTextFromPage(doc.getPage(1), filterListener);
System.out.println(extractedText);
  • 上面的例子就可以取出第一页所有的文字,如果需要取出某些文字需要知道文字的具体方位,画个矩形就可以取出
  • 以上代码依赖com.itextpdf.kernel
  1. 取出多个位置的文字
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void testWithMultiFilteredRenderListener() throws IOException {
    PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "test.pdf"));

    float x1, y1, x2, y2;

    FilteredEventListener listener = new FilteredEventListener();
    x1 = 122;
    x2 = 22;
    y1 = 678.9f;
    y2 = 12;
    ITextExtractionStrategy region1Listener = listener.attachEventListener(new LocationTextExtractionStrategy(),
            new TextRegionEventFilter(new Rectangle(x1, y1, x2, y2)));

    x1 = 156;
    x2 = 13;
    y1 = 678.9f;
    y2 = 12;
    ITextExtractionStrategy region2Listener = listener.attachEventListener(new LocationTextExtractionStrategy(),
            new TextRegionEventFilter(new Rectangle(x1, y1, x2, y2)));

    PdfCanvasProcessor parser = new PdfCanvasProcessor(new GlyphEventListener(listener));
    parser.processPageContent(pdfDocument.getPage(1));

    Assert.assertEquals("Your", region1Listener.getResultantText());
    Assert.assertEquals("dju", region2Listener.getResultantText());
}
  1. 遍历pdf每个字符
    • 之前一直以为Listen监听遍历pdf文本只能一段一段遍历,现在发现他实际上提供了遍历字符的方法
    • 两个监听器,一个监听的段落,一个监听每个字符

    static class MyEventListener implements IEventListener { private List<Rectangle> rectangles = new ArrayList<>(); @Override public void eventOccurred(IEventData data, EventType type) { if (type == EventType.RENDER_TEXT) { TextRenderInfo renderInfo = (TextRenderInfo) data; Vector startPoint = renderInfo.getDescentLine().getStartPoint(); Vector endPoint = renderInfo.getAscentLine().getEndPoint(); float x1 = Math.min(startPoint.get(0), endPoint.get(0)); float x2 = Math.max(startPoint.get(0), endPoint.get(0)); float y1 = Math.min(startPoint.get(1), endPoint.get(1)); float y2 = Math.max(startPoint.get(1), endPoint.get(1)); rectangles.add(new Rectangle(x1, y1, x2 - x1, y2 - y1)); } } @Override public Set<EventType> getSupportedEvents() { return new LinkedHashSet<>(Collections.singletonList(EventType.RENDER_TEXT)); } public List<Rectangle> getRectangles() { return rectangles; } public void clear() { rectangles.clear(); } } static class MyCharacterEventListener extends MyEventListener { @Override public void eventOccurred(IEventData data, EventType type) { if (type == EventType.RENDER_TEXT) { TextRenderInfo renderInfo = (TextRenderInfo) data; for (TextRenderInfo tri : renderInfo.getCharacterRenderInfos()) { super.eventOccurred(tri, type); } } } }

    • 标记每个字符,提供了这样的方法,可以发挥想象做更多的事,给个图片更清楚点

    private void parseAndHighlight(String input, String output, boolean singleCharacters) throws IOException { PdfDocument pdfDocument = new PdfDocument(new PdfReader(input), new PdfWriter(output)); MyEventListener myEventListener = singleCharacters ? new MyCharacterEventListener() : new MyEventListener(); PdfDocumentContentParser parser = new PdfDocumentContentParser(pdfDocument); for (int pageNum = 1; pageNum <= pdfDocument.getNumberOfPages(); pageNum++) { parser.processContent(pageNum, myEventListener); List<Rectangle> rectangles = myEventListener.getRectangles(); PdfCanvas canvas = new PdfCanvas(pdfDocument.getPage(pageNum)); canvas.setLineWidth(0.5f); canvas.setStrokeColor(ColorConstants.RED); for (Rectangle rectangle : rectangles) { canvas.rectangle(rectangle); canvas.stroke(); } myEventListener.clear(); } pdfDocument.close(); }

  • 要实现上面的效果,只要调用上面的方法即可

@Test public void highlightNotDefTest() throws IOException, InterruptedException { String input = sourceFolder + "page229.pdf"; String output = outputPath + "page229.pdf"; //false 表示短语单词为单位 true表示每个字符都遍历 parseAndHighlight(input, output, false); }

  • false的效果
  1. 定位某些单词
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void findPosition() throws Exception {
    String sourceFolder2 = "E:\\picture2\\租赁合同2.pdf";
    String output = "E:\\picture2\\租赁合同2_stroke.pdf";
    PdfReader reader = new PdfReader(sourceFolder2);
    PdfDocument pdfDocument = new PdfDocument(reader, new PdfWriter(output));
    PdfPage lastPage = pdfDocument.getLastPage();
    RegexBasedLocationExtractionStrategy strategy = new RegexBasedLocationExtractionStrategy("甲方");
    PdfCanvasProcessor canvasProcessor = new PdfCanvasProcessor(strategy);
    canvasProcessor.processPageContent(lastPage);
    Collection<IPdfTextLocation> resultantLocations = strategy.getResultantLocations();
    PdfCanvas pdfCanvas = new PdfCanvas(lastPage);
    pdfCanvas.setLineWidth(0.5f);
    List<IPdfTextLocation> sets = new ArrayList<>();
    for (IPdfTextLocation location : resultantLocations) {
        Rectangle rectangle = location.getRectangle();
        pdfCanvas.rectangle(rectangle);
        pdfCanvas.setStrokeColor(ColorConstants.RED);
        pdfCanvas.stroke();
        System.out.println(rectangle.getX() + "," + rectangle.getY() + "," + rectangle.getLeft() + "," +
                rectangle.getRight() + "," + rectangle.getTop() + "," + rectangle.getBottom() + "," +
                rectangle.getWidth() + "," + rectangle.getHeight());
        System.out.println(location.getText());
        sets.add(location);
    }
    Collections.sort(sets, new Comparator<IPdfTextLocation>() {
        @Override
        public int compare(IPdfTextLocation o1, IPdfTextLocation o2) {
            return o1.getRectangle().getY() - o2.getRectangle().getY() > 0 ? 1 : o1.getRectangle().getY() - o2.getRectangle().getY() == 0 ? 0 : -1;
        }
    });
    System.out.println(sets.get(0).getRectangle().getY());
    pdfDocument.close();
}
  • 以下是输出
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
88.0,297.53,88.0,115.72,311.53,297.53,27.720001,14.0
甲方
213.0,674.176,213.0,241.0,688.176,674.176,28.0,14.0
甲方
227.75,767.7765,227.75,254.75,781.2765,767.7765,27.0,13.5
甲方
322.25,767.7765,322.25,349.25,781.2765,767.7765,27.0,13.5
甲方
297.53
  • 上面的方法用来合同签章定位上,已经可以做到定位最后某个特定单词

添加文字和图片

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void imagesWithDifferentDepth() throws IOException, InterruptedException {
    String outFileName = destinationFolder + "transparencyTest01.pdf";
    String cmpFileName = sourceFolder + "cmp_transparencyTest01.pdf";
    PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName, new WriterProperties()
            .setCompressionLevel(CompressionConstants.NO_COMPRESSION)));
    PdfPage page = pdfDocument.addNewPage(PageSize.A3);//默认添加A4
    PdfCanvas canvas = new PdfCanvas(page);
    canvas.setFillColor(ColorConstants.LIGHT_GRAY).fill();//设置填充背景色
    canvas.rectangle(80, 0, 700, 1200).fill();
    //开始添加文字
    canvas
            .saveState()
            .beginText()
            .moveText(116, 1150) //从哪里开始写
            .setFontAndSize(PdfFontFactory.createFont(StandardFonts.HELVETICA), 14) //字体和大小
            .setFillColor(ColorConstants.MAGENTA) //字体颜色
            .showText("8 bit depth PNG") //具体展示的文字
            .endText()
            .restoreState();
    //读取并添加图片到指定位置
    ImageData img = ImageDataFactory.create(sourceFolder + "manualTransparency_8bit.png");
    canvas.addImage(img, 100, 780, 200, false);
    
    //收尾步骤,关闭画布和pdf,否则pdf打开错误
    canvas.release();
    pdfDocument.close();

}

覆盖原来的文字

  1. 由于itext没提供替换pdf文字的接口,只能通过覆盖文字的形式完成
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        PdfContentByte canvas = stamper.getUnderContent(1);
        canvas.saveState();
        canvas.setColorFill(BaseColor.YELLOW);
        canvas.rectangle(36, 786, 66, 16);
        canvas.fill();
        canvas.restoreState();
        
        //开始写入文本 
        canvas.beginText(); 
        for (Entry<String, ReplaceRegion> entry : entrys) {
            ReplaceRegion val = entry.getValue();
            //设置字体
            canvas.setFontAndSize(font.getBaseFont(), getFontSize());  
            canvas.setTextMatrix(val.getX(),val.getY()+2/*修正背景与文本的相对位置*/);
            canvas.showText((String) replaceTextMap.get(value.getAliasName()));
        }
        canvas.endText();
        
        stamper.close();
        reader.close();
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-11-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
itext实现pdf自动定位合同签订
需求 需要实现如下效果(最终效果) 思考 需求方的要求就是实现签订合同,实现方法不限,但过程中又提出需要在签章的过程中把签订日期的文字也打上去,这就有点坑了~ 一开始的想法是想办法定位需要签名的位
老梁
2019/09/10
2.4K1
itext实现pdf自动定位合同签订
Itext根据模板生成pdf
public class PdfUtils { // 利用模板生成pdf public static void pdfout(Map<String,Object> o,String newPDFPath){ // 模板路径 String templatePath = "C:/Users/pc/Desktop/990696 list -1.pdf"; // 生成的新文件路径 PdfReader reader; F
故久
2019/09/29
3.2K0
Itext根据模板生成pdf
使用iText5来处理PDF
项目要求,通过pdf模板,把用户提交的数据保存到一个PDF文件中。其中有文字内容,也有图片。之前选了aspose.pdf,因为抠门,不能花钱买,就从网上找的的开心版,好不容易出来点模板,结果插入图片的时候,同一页只能插入一张图片,而官方的试用版是可以正常两张的,另外字段比较多,速度比较慢,几百个字段需要一分多钟,效率很低,放弃。之后尝试iText,发现要比aspose.pdf好用的多,下面就说下用法。 需要通过nuget安装iTextSharp,选第一个,版本号是5.5.12,也就是iText5版本,该版本是AGPL许可。 完整代码如下:
徐大嘴
2019/03/21
2.6K0
C# iText 7 切分PDF,处理PDF页面大小
我要使用itext做一个pdf的页面大小一致性处理,然后再根据数据切分出需要的pdf.
SpringSun
2022/04/28
1.3K0
C#  iText 7 切分PDF,处理PDF页面大小
leetcode391. Perfect Rectangle
用一个二维数组来表示一堆矩形,二维数组中的每一行分别记录矩形左下角和右上角的坐标。试判断这些矩形拼接成的新的图形是否还是一个矩形。如果矩形存在重合,则不构成矩形,见图例4.
眯眯眼的猫头鹰
2019/03/20
3450
leetcode391. Perfect Rectangle
itext根据模板生成pdf(支持分页)
// 利用模板生成pdf public static void pdfout(Map<String,Object> o,String newPDFPath){ // 模板路径 File file = new File(""); String filePath = null; try { filePath = file.getCanonicalPath(); } catch (IOException e) { e.printStackTrace(); } System.out.println(filePath); String templatePath = "C:/Users/pc/Desktop/990696 list -1.pdf"; String templatePaths = "C:/Users/pc/Desktop/990696 list -2.pdf"; // 生成的新文件路径 PdfReader reader; PdfReader readers; FileOutputStream out;
故久
2019/09/29
4K0
itext根据模板生成pdf(支持分页)
HDOJ 2056 Rectangles
Problem Description Given two rectangles and the coordinates of two points on the diagonals of each rectangle,you have to calculate the area of the intersected part of two rectangles. its sides are parallel to OX and OY .
谙忆
2021/01/20
2350
itext实现合同尾部签章部分自动添加,定位签名
使用的pom <!-- pdf处理 start--> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <vers
老梁
2019/09/10
1.6K0
itext实现合同尾部签章部分自动添加,定位签名
AIM Tech Round 5 (rated, Div. 1 + Div. 2)C. Rectangles
You are given nn rectangles on a plane with coordinates of their bottom left and upper right points. Some (n−1)(n−1) of the given nn rectangles have some common point. A point belongs to a rectangle if this point is strictly inside the rectangle or belongs to its boundary.
glm233
2020/09/28
3030
AIM Tech Round 5 (rated, Div. 1 + Div. 2)C. Rectangles
HDU 1866 A + B forever!
A + B forever! Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1171    Accepted Submission(s): 268 Problem Description As always, A + B is the necessary problem of this warming-up contest. But t
ShenduCC
2018/04/26
5680
reportlab教程1--第一个pdf生成
        实际生活工作中,我们会希望有些报告、图表可以自动生成,然后变成pdf,甚至直接发邮件到某个制定邮箱lib。这个时候有几种方式可以来实现,譬如用latex,但是这个似乎还要在电脑上装很多东西。还有一个pdfkit的东西,直接把html转成pdf,不过也要装一个插件。虽然实现起来可能pdfkit更简单,但是从功能角度来讲,似乎是report更加强,而且文档也丰富。
钱塘小甲子
2019/01/28
2.8K0
根据 PDF 模板产生各种电子订单
然后使用 Adobe Acrobat 软件打开,然后创建一个表单,打开 acrobat, 点击工具,点击准备表单
BUG弄潮儿
2021/12/01
8220
根据 PDF 模板产生各种电子订单
Java输出Pdf(2021)集成springboot
1.首先,新建一个word文档,内容如下,另存为pdf格式,我的命名:mytest.pdf。
知识浅谈
2021/05/10
1.1K0
Java输出Pdf(2021)集成springboot
Java开发画板
Test类 public class Test { public static void main(String[] args){ DrawBoard db = new DrawBoard(); db.initFrame(); } } DrawBoard类 public class DrawBoard extends JFrame { Graphics2D g; public
Java帮帮
2018/03/16
1.8K0
Java开发画板
2022-10-09:我们给出了一个(轴对齐的)二维矩形列表 rectangles 。 对于 rectangle[i] = [x1, y1, x2, y2],其
2022-10-09:我们给出了一个(轴对齐的)二维矩形列表 rectangles 。
福大大架构师每日一题
2022/10/09
2840
2022-10-09:我们给出了一个(轴对齐的)二维矩形列表 rectangles 。 对于 rectangle[i] = [x1, y1, x2, y2],其
详解Java操作PDF:一键生成文件,插入文字、选项、签名及公章
我这里使用福昕pdf编辑器,其他pdf编辑器(如Adobe Acrobat)也可以用但是大多要钱。
程序员皮皮林
2024/11/02
2540
详解Java操作PDF:一键生成文件,插入文字、选项、签名及公章
WPF实现界面动态布局
曾经总认为动态布局是个非常麻烦的问题。是个非常须要功力的问题。可是貌似在.NET中,在WPF中却不是那么的麻烦。以下介绍我如今实现的一个动态布局的实例。
全栈程序员站长
2022/07/08
1.1K0
LeetCode 391. 完美矩形(set检查顶点+面积检查)
我们有 N 个与坐标轴对齐的矩形, 其中 N > 0, 判断它们是否能精确地覆盖一个矩形区域。
Michael阿明
2020/07/13
5720
LeetCode 391. 完美矩形(set检查顶点+面积检查)
用Python中的tkinter模块作图
tkinter 可以用来创建完整的应用程序,比如简单的字处理软件,还有简单的绘图软件。 一、创建一个可以点的按钮 用tkinter创建一个带按钮的简单程序,代码如下: >>> from tkinter import* >>> tk = Tk() >>> btn = Button(tk,text = "click me") >>> btn.pack() 在第一行上,我们引入了 tkinter 模块的内容。用 from 模块名 import* 就可以在不用模块名字的情况下使用模块的内容了。 下面是我们创建的按钮
Zoctopus
2018/06/04
6K5
java导出pdf模板_java模板导出PDF[通俗易懂]
一对一,点对点的给对应的地方写值,比如模板里面放了个name标识,在程序里把“张三”赋给name,那么输出的pdf里面name的地方就变成了张三,准确方便快捷
全栈程序员站长
2022/08/25
2.6K0
java导出pdf模板_java模板导出PDF[通俗易懂]
推荐阅读
相关推荐
itext实现pdf自动定位合同签订
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验