【PDFBox】PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档

这篇具有很好参考价值的文章主要介绍了【PDFBox】PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这篇文章,主要介绍PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档。

目录

一、PDFBox操作文本

1.1、读取所有页面文本内容

1.2、读取指定页面文本内容

1.3、写入文本内容

1.4、替换文本内容

(1)自定义PDTextStripper类

(2)创建KeyWordEntity实体类

(3)下载字体文件

(4)创建PDFUtil工具类

(5)运行效果

(6)不足之处


一、PDFBox操作文本

PDFBox操作文本内容,需要使用文本提取器PDTextStripper对象实现,这个PDTextStripper类提供了对文本内容操作的方法,例如:getText()获取文本,writeString()写入字符串等等,下面介绍PDFBox操作文本的几种情况。

1.1、读取所有页面文本内容

一个PDF文档是由多个页面组成的,某一个页面中都可能会包含文本内容,PDTextStripper类提供的【getText()】方法,可以获取到整个PDF文档的文本内容,案例代码如下所示:

package pdfbox.demo.text;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;
import java.io.IOException;

/**
 * @version 1.0.0
 * @Date: 2023/7/18 9:03
 * @Author ZhuYouBin
 * @Description: 读取PDF文档中所有纯文本内容
 */
public class ReadAllText {
    public static void main(String[] args) throws IOException {
        // 1、加载指定PDF文档
        PDDocument document = PDDocument.load(new File("D:\\demo.pdf"));
        // 2、创建文本提取对象
        PDFTextStripper stripper = new PDFTextStripper();
        // 3、获取指定页面的文本内容
        String text = stripper.getText(document);
        System.out.println("获取文本内容: " + text);
        // 4、关闭
        document.close();
    }
}

1.2、读取指定页面文本内容

有些情况下,我们可能是需要获取某一个页面中的文本内容,这个时候可以通过PDTextStripper类设置页面边界,也就是设置提取哪些页面中的文本内容,只需要调用【setStartPage()】和【setEndPage()】方法即可,案例代码如下所示:

package pdfbox.demo.text;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;
import java.io.IOException;

/**
 * @version 1.0.0
 * @Date: 2023/7/18 9:03
 * @Author ZhuYouBin
 * @Description: 读取PDF文档中所有纯文本内容
 */
public class ReadPageText {
    public static void main(String[] args) throws IOException {
        // 1、加载指定PDF文档
        PDDocument document = PDDocument.load(new File("D:\\demo.pdf"));
        // 2、创建文本提取对象
        PDFTextStripper stripper = new PDFTextStripper();
        // 指定页面读取内容
        stripper.setStartPage(0); // 设置起始页面,这里设置成0,就表示读取第一个页面
        stripper.setEndPage(0); // 设置结束页面,这里设置成0,就表示读取第一个页面
        // 3、获取指定页面的文本内容
        String text = stripper.getText(document);
        System.out.println("获取文本内容: " + text);
        // 4、关闭
        document.close();
    }
}

1.3、写入文本内容

前几篇文章已经介绍过了如何使用PDFBox写入纯文本内容到PDF文档里面,写入内容可以写入单行内容,也可以写入多行文本内容,可以参考文章:

【【PDFBox】PDFBox操作PDF文档之创建PDF文档、加载PDF文档、添加空白页面、删除页面、获取总页数、添加文本内容、PDFBox坐标系】。

1.4、替换文本内容

替换文本内容,PDFBox并没有提供替换文本内容的方法,这里我是采用了某种方式来实现替换文本内容的功能,大致思路:

  • 首先读取文本内容,获取到替换的文本在PDF文档中的页面坐标位置。
  • 获取到替换文本的坐标之后,将这块区域内容写入一个矩形框,矩形背景颜色采用白色,也就是覆盖替换的文本。
  • 在白色矩形区域里面,重新写入替换之后的文本内容。
  • 采用这种思路,就可以大致实现替换指定文本的功能啦。

(1)自定义PDTextStripper类

要想获取到文本的坐标信息,必须自定义一个类,继承自PDTextStripper类,然后重写【writeString()】方法,这个方法有两个参数:

  • 第一个参数是text:表示当前读取到的文本内容。
  • 第二个参数是List<TextPosition>:表示当前文本内容中某一个字符的坐标信息。
package pdfbox.demo.text.keyword;

import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import org.apache.pdfbox.util.Matrix;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @version 1.0.0
 * @Date: 2023/7/18 10:18
 * @Author ZhuYouBin
 * @Description: 自定义文本提取器,获取查找文本的坐标位置
 */
public class KeyWordPositionStripper extends PDFTextStripper {

    /**
     * 查找的关键字集合
     */
    private final List<String> keyWordList;
    /**
     * 查找成功的关键字实体对象集合
     */
    private final List<KeyWordEntity> keyWordEntityList = new ArrayList<>();

    public KeyWordPositionStripper(List<String> keyWordList) throws IOException {
        this.keyWordList = keyWordList;
    }

    @Override
    protected void writeString(String text, List<TextPosition> positions) {
        int size = positions.size();
        for (String keyWord : keyWordList) {
            char[] chars = keyWord.toCharArray();
            for (int i = 0; i < size; i++) {
                // 获取当前读取的字符
                String currentChar = positions.get(i).getUnicode();
                // 当前字符 和 keyWord 关键字进行匹配
                if (!Objects.equals(currentChar, String.valueOf(chars[0]))) {
                    continue;
                }
                int count = 1;
                int j;
                for (j = 1; j < chars.length && i + j < size; j++) {
                    currentChar = positions.get(i + j).getUnicode();
                    if (!Objects.equals(currentChar, String.valueOf(chars[j]))) {
                        break;
                    }
                    count++;
                }
                // 匹配成功,记录文本的坐标位置
                if (count == chars.length) {
                    TextPosition startPosition = positions.get(i);
                    TextPosition endPosition = positions.get(i + j < size ? i + j : i + j - 1);
                    // 创建实体对象
                    KeyWordEntity entity = new KeyWordEntity();
                    entity.setKeyWord(keyWord);
                    // 获取起始字符坐标
                    Matrix matrix = startPosition.getTextMatrix();
                    float x = matrix.getTranslateX();
                    float y = matrix.getTranslateY();
                    // 获取结束字符坐标
                    Matrix endMatrix = endPosition.getTextMatrix();
                    float x2 = endMatrix.getTranslateX();
                    // 获取字体大小
                    float fontSizeInPt = startPosition.getFontSizeInPt();
                    entity.setX(x);
                    entity.setY(y - fontSizeInPt / 5);
                    float width = i + j < size ? x2 - x : x2 - x + fontSizeInPt;
                    entity.setWidth(width);
                    entity.setHeight(fontSizeInPt);
                    keyWordEntityList.add(entity);
                }
            }
        }
    }

    public List<KeyWordEntity> getKeyWordEntityList() {
        return keyWordEntityList;
    }
}

(2)创建KeyWordEntity实体类

创建一个KeyWordEntity实体类,用于表示需要查找的关键字文本,关键字也就是我们需要替换的文本内容,一般在实际开发中,就相当于是模板占位符内容。实体类需要设置关键字名称、文本的坐标信息。

package pdfbox.demo.text.keyword;

import java.io.Serializable;

/**
 * @version 1.0.0
 * @Date: 2023/7/18 11:22
 * @Author ZhuYouBin
 * @Description: 查找的关键字
 */
public class KeyWordEntity implements Serializable {
    private String keyWord;

    private float x;
    private float y;
    private float width;
    private float height;

    public String getKeyWord() {
        return keyWord;
    }

    public void setKeyWord(String keyWord) {
        this.keyWord = keyWord;
    }

    public float getX() {
        return x;
    }

    public void setX(float x) {
        this.x = x;
    }

    public float getY() {
        return y;
    }

    public void setY(float y) {
        this.y = y;
    }

    public float getWidth() {
        return width;
    }

    public void setWidth(float width) {
        this.width = width;
    }

    public float getHeight() {
        return height;
    }

    public void setHeight(float height) {
        this.height = height;
    }
}

(3)下载字体文件

如果你不想使用PDFBox提供的字体,那么你可以使用外部字体文件,字体文件可以去【经典宋体简|经典|字体下载】网站下载。

(4)创建PDFUtil工具类

package pdfbox.demo.text.keyword;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.springframework.core.io.ClassPathResource;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.List;

/**
 * @version 1.0.0
 * @Date: 2023/7/18 16:01
 * @Author ZhuYouBin
 * @Description: 基于PDFBox的工具类
 */
public class PDFUtil {

    /**
     * 读取PDF模板文件,替换指定关键字的数据
     * @param keyWordMap 需要替换的关键字数据,key表示占位符,value表示替换后的内容
     * @param pdfPath PDF模板文件的路径
     * @param destPdf 生成的目标PDF文件
     */
    public static void replaceText(Map<String, String> keyWordMap, String pdfPath, String destPdf) throws IOException {
        if (keyWordMap == null || keyWordMap.keySet().size() <= 0) {
            return;
        }
        Set<String> keyWordSet = keyWordMap.keySet();
        // 1、读取PDF模板文件
        PDDocument document = PDDocument.load(new File(pdfPath));
        // 2、创建自定义文本提取器
        KeyWordPositionStripper stripper = new KeyWordPositionStripper(new ArrayList<>(keyWordSet));
        stripper.setSortByPosition(true);
        // 注意: writeString() 方法必须执行 getText() 方法之后才会执行
        stripper.getText(document);
        // 3、获取关键字实体对象
        List<KeyWordEntity> keyWordEntityList = stripper.getKeyWordEntityList();
        // 4、替换指定关键字文本内容
        PDPageContentStream stream = new PDPageContentStream(document, document.getPage(0), PDPageContentStream.AppendMode.APPEND, true);
        // 5、加载外部字体文件,这里是直接通过File加载,如果你是SpringBoot项目,则可以通过流加载
        PDType0Font font = PDType0Font.load(document, new File("D:\\simsun.ttf"));
        // 6、循环替换文本内容
        for (KeyWordEntity keyWord : keyWordEntityList) {
            stream.setNonStrokingColor(Color.WHITE);
            stream.addRect(keyWord.getX(), keyWord.getY(), keyWord.getWidth(), keyWord.getHeight());
            stream.fill();
            // 设置画笔颜色
            stream.setNonStrokingColor(Color.BLACK);
            // 替换关键字文本内容
            stream.beginText();
            stream.setFont(font, 14);
            stream.newLineAtOffset(keyWord.getX(), keyWord.getY());
            stream.showText(keyWordMap.get(keyWord.getKeyWord()));
            stream.endText();
        }
        // 关闭内容流
        stream.close();
        // 保存替换之后的文档
        document.save(destPdf);
        // 关闭文档
        document.close();
    }

    public static void main(String[] args) throws IOException {
        Map<String, String> keyWordMap = new HashMap<>();
        keyWordMap.put("{{name}}", "张三");
        keyWordMap.put("{{age}}", "25");
        keyWordMap.put("{{sex}}", "男");
        keyWordMap.put("{{address}}", "福建省厦门市");
        // 模拟测试
        PDFUtil.replaceText(keyWordMap, "D:\\pdfbox-template.pdf", "D:\\new-document.pdf");
    }
}

(5)运行效果

这里的PDF模板文件如下图所示:

【PDFBox】PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档,【WPSP笔记】,pdf,PDFBox,PDF文档操作,Java操作PDF文档,java生成pdf

使用PDFBox替换模板文件的内容之后,运行结果如下所示:

【PDFBox】PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档,【WPSP笔记】,pdf,PDFBox,PDF文档操作,Java操作PDF文档,java生成pdf

(6)不足之处

虽然这里可以实现替换文本内容,但是这个代码仍然存在一些不足之处,有以下几点:

  • 1、替换的文本位置无法保证和原文本内容对齐,需要自己根据实际模板,调整相应坐标位置。
  • 2、当替换的文本内容太多,会覆盖后面的文本内容。
  • 3、目前只能够替换指定页面的文本内容。
  • 4、其他不足。。。

到此,PDFBox操作文本就介绍完啦。

综上,这篇文章结束了,主要介绍PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档。文章来源地址https://www.toymoban.com/news/detail-599124.html

到了这里,关于【PDFBox】PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java实战:高效提取PDF文件指定坐标的文本内容

    临时接到一个紧急需要处理的事项。业务侧一个同事有几千个PDF文件需要整理:需要从文件中的指定位置获取对应的编号和地址。 要的急,工作量大。所以就问到技术部有没有好的解决方案。 问技术的话就只能写个demo跑下了。 PDF的文档看起来比较简单,因为只是需要读取两

    2024年02月13日
    浏览(57)
  • JAVA读取(DOC、DOCX、PDF、PPT、PPTX)文件文本内容及图片

    温馨提示:有很多方法均可以解析这些常见的文件,以下内容使用的是apache-poi + apache-pdfbox实现的。         关于文档解析,在网上搜索了很久,无奈内容太过繁杂,找不到合适的代码,一大半都是只支持文本。没办法,只能自己在网上一点一点CV了,最终提取了这些代码

    2024年02月03日
    浏览(51)
  • Java 利用pdfbox将图片和成到pdf指定位置

    业务背景:用户在手机APP上进行签名,前端将签完名字的图片传入后端,后端合成新的pdf. 废话不多说,上代码: 注意:前端传过来的图片必须是透明的,否则合成的时候签名处会有边框        

    2024年02月09日
    浏览(65)
  • java中pdfbox处理pdf常用方法(读取、写入、合并、拆分、写文字、写图片)

    方法代码: 测试用例: 2.1写文字 方法代码: 测试用例: A.pdf: A2.pdf: 2.2写图片 方法代码: 测试用例: A.pdf: pic.jpg: A2.pdf: 方法代码: 测试用例: 方法代码: 测试用例: 引用链接: (17条消息) 使用Apache PDFBox实现拆分、合并PDF_似有风中泣的博客-CSDN博客 (17条消息) Java使用P

    2024年02月11日
    浏览(128)
  • 【itext7】itext7操作PDF文档之创建PDF文档、加载PDF文档、添加空白页、操作PDF页面、itext中的常见类及其方法

    这篇文章,主要介绍itext7操作PDF文档之创建PDF文档、加载PDF文档、添加空白页、操作PDF页面、itext中的常见类及其方法。 目录 一、itext7操作PDF 1.1、itext7介绍 1.2、引入itext-core依赖 1.3、创建PDF文档 1.4、加载PDF文档 1.5、操作PDF页面 1.6、添加空白页面 二、itext常见类和方法 2.1、

    2024年02月16日
    浏览(47)
  • Python3,9行批量提取PDF文件的指定内容,这种操作,保证人见人爱....

    小屌丝 :鱼哥, 你有没有什么办法,提取PDF文档的内容。 小鱼 :这个还问我?? 小屌丝 :哎呀,这个不是被难住了嘛 。 小鱼 :有啥难得?提示你一下, 小屌丝 :嗯,可以可以。 小鱼 :去我的博文找,没记错的话,有两种方法提取pdf的文字。 小屌丝 :好嘞, 我这就去

    2024年02月04日
    浏览(46)
  • Powershell删除文本指定内容所在行以下内容

    需求:批量获取文本指定内容所在行以下内容(含当前行)   解决方案:使用Powershell脚本处理   案例: 获取当前文件夹下所有txt文件 含文本\\\"4\\\"所在行 以下内容(含当前行) 如果有多行包含文本\\\"4\\\",取第一个所在行以下内容(含当前行)   1.查看当前文件夹内容   2.右键执

    2024年01月20日
    浏览(39)
  • java 读取pdf文件内容

    https://blog.csdn.net/ThinkPet/article/details/131256428

    2024年02月08日
    浏览(45)
  • MFC读取文本内容

    MFC (Microsoft Foundation Classes) 是微软提供的一种 C++ 编程框架,用于开发 Windows 应用程序。要在 MFC 中读取文本内容,需要使用 CFile 类的 Open、Read、Close 方法。 使用 Open 方法打开文件,可以指定打开模式(读、写、读写等)。 使用 Read 方法读取文件中的内容,可以指定读取的字节

    2024年02月09日
    浏览(42)
  • Java按行读取文件文本内容

    在工作和学习中,有时候会有一些场景,代码需要配合读取文件来执行,比如:读文件数据,来进行计算、组装SQL、更新操作...... 下面我们来讨论下,在Java中按行读取文件文件内容的方式有哪些? 读取的文件内容 测试代码 输出结果 分析:虽然读取1个字符,但每行后面可能

    2024年02月15日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包