java 读取PDF文件内容进行替换
需要使用到的包
监听类(对需要替换的内容关键词进行匹配)
实体类(保存关键字字体格式信息以及其位置)
工具类(对关键字进行替换)
测试类
需要使用到的包
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13.3</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

监听类(对需要替换的内容关键词进行匹配)
public class KeyWordPositionListener implements RenderListener {

//存放匹配上的字符信息
    private List<MatchItem> matches = new ArrayList<MatchItem>();
    //存放所有的字符信息
    private List<MatchItem> allItems = new ArrayList<MatchItem>();

private Rectangle curPageSize;

/**
     * 匹配的关键字
     */
    private String keyword;
    /**
     * 匹配的当前页
     */
    private Integer pageNumber;

@Override
    public void beginTextBlock() {
        //do nothing
    }

@Override
    public void renderText(TextRenderInfo renderInfo) {
        //获取字符
        String content = renderInfo.getText();
        Rectangle2D.Float textRectangle = renderInfo.getDescentLine().getBoundingRectange();

MatchItem item = new MatchItem();
        item.setContent(content);
        item.setPageNum(pageNumber);
        item.setFontHeight(textRectangle.height == 0 ? 12:textRectangle.height);//默认12
        item.setFontWidth(textRectangle.width);
        item.setPageHeight(curPageSize.getHeight());
        item.setPageWidth(curPageSize.getWidth());
        item.setX((float)textRectangle.getX());
        item.setY((float)textRectangle.getY());

//若keyword是单个字符,匹配上的情况
        if(content.equalsIgnoreCase(keyword)) {
            matches.add(item);
        }
        //保存所有的项
        allItems.add(item);
    }

@Override
    public void endTextBlock() {
        //do nothing
    }

@Override
    public void renderImage(ImageRenderInfo renderInfo) {
        //do nothing
    }

/**
     * 设置需要匹配的当前页
     * @param pageNumber
     */
    public void setPageNumber(Integer pageNumber) {
        this.pageNumber = pageNumber;
    }

/**
     * 设置需要匹配的关键字,忽略大小写
     * @param keyword
     */
    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

/**
     * 返回匹配的结果列表
     * @return
     */
    public List<MatchItem> getMatches() {
        return matches;
    }

public void setCurPageSize(Rectangle rect) {
        this.curPageSize = rect;
    }

public List<MatchItem> getAllItems() {
        return allItems;
    }

public void setAllItems(List<MatchItem> allItems) {
        this.allItems = allItems;
    }

}
实体类(保存关键字字体格式信息以及其位置)
public class MatchItem {

//页数
    private Integer pageNum;
    //x坐标
    private Float x;
    //y坐标
    private Float y;
    //页宽
    private Float pageWidth;
    //页高
    private Float pageHeight;
    //匹配字符
    private String content;
    //字体宽
    private float fontWidth;
    //字体高
    private float fontHeight = 12;

public Integer getPageNum() {
        return pageNum;
    }

public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }

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 getPageWidth() {
        return pageWidth;
    }

public void setPageWidth(Float pageWidth) {
        this.pageWidth = pageWidth;
    }

public Float getPageHeight() {
        return pageHeight;
    }

public void setPageHeight(Float pageHeight) {
        this.pageHeight = pageHeight;
    }

public String getContent() {
        return content;
    }

public void setContent(String content) {
        this.content = content;
    }

public float getFontWidth() {
        return fontWidth;
    }

public void setFontWidth(float fontWidth) {
        this.fontWidth = fontWidth;
    }

public float getFontHeight() {
        return fontHeight;
    }

public void setFontHeight(float fontHeight) {
        this.fontHeight = fontHeight;
    }

@Override
    public String toString() {
        return "MatchItem{" +
                "pageNum=" + pageNum +
                ", x=" + x +
                ", y=" + y +
                ", pageWidth=" + pageWidth +
                ", pageHeight=" + pageHeight +
                ", content='" + content + '\'' +
                '}';
    }
}

工具类(对关键字进行替换)
public class PdfUtil {
    /**
     * 根据关键字和pdf文件字节,全文搜索关键字
     * @param bytes pdf字节
     * @param keyword 关键字
     * @return
     * @throws Exception
     */
    private static List<MatchItem> matchAll(byte[] bytes, String keyword) throws Exception {
        List<MatchItem> items = new ArrayList<>();
        PdfReader reader = new PdfReader(bytes);
        //获取pdf页数
        int pageSize = reader.getNumberOfPages();
        //逐页匹配关键字
        for(int page = 1;page <= pageSize;page++){
            items.addAll(matchPage(reader,page,keyword));
        }
        return items;
    }

/**
     * 根据关键字、文档路径、pdf页数寻找特定的文件内容
     * @param reader
     * @param pageNumber 页数
     * @param keyword 关键字
     * @return
     * @throws Exception
     */
    private static List<MatchItem> matchPage(PdfReader reader, Integer pageNumber,String keyword) throws Exception {
        PdfReaderContentParser parse = new PdfReaderContentParser(reader);
        Rectangle rectangle = reader.getPageSize(pageNumber);
        //匹配监听
        KeyWordPositionListener renderListener = new KeyWordPositionListener();
        renderListener.setKeyword(keyword);
        renderListener.setPageNumber(pageNumber);
        renderListener.setCurPageSize(rectangle);
        parse.processContent(pageNumber, renderListener);
        return findKeywordItems(renderListener,keyword);
    }

/**
     * 找到匹配的关键词块
     * @param renderListener
     * @param keyword
     * @return
     */
    private static List<MatchItem> findKeywordItems(KeyWordPositionListener renderListener,String keyword){
        //先判断本页中是否存在关键词
        List<MatchItem> allItems = renderListener.getAllItems();//所有块LIST
        StringBuffer sbtemp = new StringBuffer("");

for(MatchItem item : allItems){//将一页中所有的块内容连接起来组成一个字符串。
            sbtemp.append(item.getContent());
        }

List<MatchItem> matches = renderListener.getMatches();

//一页组成的字符串没有关键词,直接return
        //第一种情况:关键词与块内容完全匹配的项,直接返回
        if(sbtemp.toString().indexOf(keyword) == -1 || matches.size() > 0){
            return matches;
        }
        //第二种情况:多个块内容拼成一个关键词,则一个一个来匹配,组装成一个关键词
        sbtemp = new StringBuffer("");
        List<MatchItem> tempItems = new ArrayList();
        for(MatchItem item : allItems){
            if(keyword.indexOf(item.getContent()) != -1 ){
                tempItems.add(item);
                sbtemp.append(item.getContent());

if(keyword.indexOf(sbtemp.toString()) == -1){//如果暂存的字符串和关键词 不再匹配时
                    sbtemp = new StringBuffer(item.getContent());
                    tempItems.clear();
                    tempItems.add(item);
                }

if(sbtemp.toString().equalsIgnoreCase(keyword)){//暂存的字符串正好匹配到关键词时
                    matches.add(tempItems.get(0));//得到匹配的项
                    sbtemp = new StringBuffer("");//清空暂存的字符串
                    tempItems.clear();//清空暂存的LIST
                    continue;//继续查找
                }
            }else{//如果找不到则清空
                sbtemp = new StringBuffer("");
                tempItems.clear();
            }
        }
        return matches;
    }

/**
     * 替换目标文字,生成新的pdf文件
     * @param bytes 目标pdf
     * @param outputStream
     * @throws Exception
     */
    private static void manipulatePdf(byte[] bytes,OutputStream outputStream,List<MatchItem> matchItems,String keyWord,String keyWordNew) throws Exception{
        PdfReader reader = new PdfReader(bytes);
        PdfStamper stamper = new PdfStamper(reader, outputStream);
        PdfContentByte canvas;
        Map<Integer,List<MatchItem>> mapItem = new HashMap<>();
        List<MatchItem> itemList;
        for(MatchItem item : matchItems){
            Integer pageNum = item.getPageNum();
            if(mapItem.containsKey(pageNum)){
                itemList = mapItem.get(pageNum);
                itemList.add(item);
                mapItem.put(pageNum,itemList);
            }else{
                itemList = new ArrayList<>();
                itemList.add(item);
                mapItem.put(pageNum,itemList);
            }
        }
        //遍历每一页去修改
        for(Integer page : mapItem.keySet()){
            List<MatchItem> items = mapItem.get(page);
            //遍历每一页中的匹配项
            for(MatchItem item : items){
                canvas = stamper.getOverContent(page);
                float x = item.getX();
                float y = item.getY();
                float fontWidth = item.getFontWidth();
                float fontHeight = item.getFontHeight();
                canvas.saveState();
                canvas.setColorFill(BaseColor.WHITE);
                canvas.rectangle(x, y,fontWidth*keyWord.length(),fontWidth+2);
                canvas.fill();
                canvas.restoreState();
                //开始写入文本
                canvas.beginText();
                BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
                Font font = new Font(bf,fontWidth,Font.BOLD);
                //设置字体和大小
                canvas.setFontAndSize(font.getBaseFont(), fontWidth);
                //设置字体的输出位置
                canvas.setTextMatrix(x, y+fontWidth/10+0.5f);
                //要输出的text
                canvas.showText(keyWordNew);

canvas.endText();
            }
        }
        stamper.close();
        reader.close();
    }

/**
     * 替换pdf中指定文字
     * @param srcBytes 目标pdf
     * @param outputStream 新pdf
     * @param keyWord 替换的文字
     * @param keyWordNew 替换后的文字
     * @throws Exception
     */
    public static void pdfReplace(byte[] srcBytes,OutputStream outputStream,String keyWord,String keyWordNew) throws Exception{
        manipulatePdf(srcBytes,outputStream,matchAll(srcBytes,keyWord),keyWord,keyWordNew);
    }
}

测试类
public class test{
public static void main(String[] args) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        FileInputStream inputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            //源文件pdf
            File file = new File("D:\\test.pdf");
            //目标文件
            File destFile = new File("D:\\dest.pdf");
            inputStream = new FileInputStream(file);
            fileOutputStream = new FileOutputStream(destFile);
            byte[] bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            //关键字
            String keyWord = "请选择";
            //替换后的内容
            String keyWordNew = "你爸爸";
            PdfUtil.pdfReplace(bytes,outputStream,keyWord,keyWordNew);
            //得到替换后的文件字节
            byte[] byteArray = outputStream.toByteArray();
            //输出
            fileOutputStream.write(byteArray);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (fileOutputStream != null) fileOutputStream.close();
                if (inputStream != null) inputStream.close();
                outputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

JAVA 替换pdf中文字相关推荐

  1. java 替换pdf中的文字

    1.引入依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian< ...

  2. JAVA替换PDF文字

    前言: 以下是通过网上查阅资料,东拼西凑实现的一个使用java替换pdf文字的功能.使用的是itextpdf.jar 参考: https://blog.csdn.net/sdizoea/article ...

  3. python pdf删除图片_使用PyMuPdf提取、删除及替换PDF中的图片文件

    有时候想把PDF中的图片文件提取出来,身为程序员的我当然是自己写段代码来实现,先看看了网上的方法,都是逐行遍历,正则匹配来提取什么的,其实没有那么复杂,PyMuPdf官方文档里自带就有提取图片文件的方 ...

  4. 使用PyMuPdf提取、删除及替换PDF中的图片文件

    有时候想把PDF中的图片文件提取出来,身为程序员的我当然是自己写段代码来实现,先看看了网上的方法,都是逐行遍历,正则匹配来提取什么的,其实没有那么复杂,PyMuPdf官方文档里自带就有提取图片文件的方 ...

  5. pdfparser java_如何使用java从PDF中提取内容?

    在Java编程中,如何使用java从PDF中提取内容? 项目的目录结构如下 - Tika的工具包可从以下网址下载:http://tika.apache.org/download.html ,只下载:t ...

  6. java替换html中的样式

    package com.yz.yrh.integration;import java.util.regex.Pattern;/*** Created by Administrator on 2017/ ...

  7. java替换数组中的元素_如何使用Java 8流快速替换列表中的元素

    java替换数组中的元素 假设您有一个项目清单: List<String> books = Arrays.asList("The Holy Cow: The Bovine Tes ...

  8. PDF文件怎么修改,如何替换PDF中的一页

    在很多的时候,我们都会使用到PDF文件,对于PDF文件,不熟悉的小伙伴,还是会头疼的,而熟悉的小伙伴会知道,修改编辑PDF文件,是需要使用到PDF编辑器的,在编辑文件的时候,怎样替换文件中的页面呢,不 ...

  9. 修改PDF中文字好用的软件,PDF编辑软件,adobe acrobat DC安装教程,adobe acrobat DC和 adobe acrobat pro的区别,

    目录 修改PDF中文字好用的软件,PDF编辑软件 adobe acrobat DC和 adobe acrobat  pro的区别 adobe acrobat DC安装教程 下载资源的安装包,我已经放到 ...

最新文章

  1. spring 基于XML的申明式AspectJ通知的执行顺序
  2. Linux 运维工程师入门须掌握的 10 个技术点
  3. bash 脚本的自解压流程
  4. RateLimiter 的底层实现是啥?
  5. VC 6.0中添加库文件和头文件
  6. Newton-Raphson method
  7. mysql差异备份实现_结合Git实现Mysql差异备份,可用于生产环境
  8. 使用protostuff进行序列化
  9. CCF201703-1 分蛋糕
  10. HDU1042 n!【大数+万进制】
  11. MySQL 索引失效案例
  12. paip.asp VBS开发IDE VBSEDIT总结
  13. JavaScript高级程序设计学习笔记(一)
  14. 分页组件extremeComponents的使用
  15. js自执行函数前加个分号是什么意思?
  16. 为什么发音要浊化(sp、st、sk)
  17. 在 Light Trail Adventures 中探索失落已久的复古未来沙漠城市
  18. 电脑的显卡驱动需要更新吗?
  19. 【洛谷】P1150 Peter的烟(配数学证明)
  20. 如何在REST API中使用查阅项的值作为过滤条件

热门文章

  1. 五分钟告诉你什么是MySQL的覆盖索引
  2. 怎么实现一个系统的消息提醒功能
  3. CSS Loading 加载效果
  4. python 来源软件应急处理_Mac遇到挖矿程序的应急方法
  5. 金多多解读高度板前锋电子无溢价
  6. Linux——进程间通信的常见方法(管道、信号、共享映射区、本地套接字)、管道的了解与简单用法
  7. java 单体应用如何优雅的使用 fegin
  8. fegin接口下载文件
  9. 读书笔记之:Linux程序设计(第4版)(ch1-7) [ 学如逆水行舟,不进则退
  10. [DataAnalysis]为什么说熵是不确定性的度量