替换pdf中的文字

文章介绍了在PDF文件中替换文字的两种方法:一是通过创建PDF表单并使用代码填充数据;二是直接定位文字位置进行覆盖。前者适用于对文档质量要求高的场景,后者则适合简单的展现需求。此外,还提供了Java代码示例来说明这两种方法的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在项目中经常会有一种需求,给定一个pdf模板,向里面空格中填充文字。若文字长度是固定的或长度变化不大,可以直接使用pdf模板来替换;若需要替换的新文字长度变动比较大,最好的办法是先做好一个word版的目标,替换文字后再转换为pdf文件(请参考:实现Word转Pdf文件)。

下面介绍pdf文件中的文字替换的两种方法。

1.通过表单来制作pdf文档,并通过代码替换。

制作包含表单的的pdf文档需要具有编辑pdf功能的编辑软件来制作,例如祈福pdf编辑器,adobe pdf编辑器,万兴pdf编辑器等都有添加表单的功能,只是一般需要付费或开通会员,才能使用。具体制作方法可以在网上搜索或参考官方文档,这里不做介绍。下面是表单字段替换的代码,仅供参考:

    /**
     * 填充表单中的数据
     * @param template 带表单字段的pdf模板输入流
     * @param data 要填充的数据
     * @param output 填充值后的pdf输出流
     * @throws IOException 可能抛出的异常类型。
     */
    public static void fillForm(InputStream template, Map<String,String> data, OutputStream output) throws IOException {
        try(PdfDocument doc = new PdfDocument(new PdfReader(template), new PdfWriter(output))){
            //设置支持汉字的字体,否则汉字不显示。
            PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", false);
            //获取pdf中的表单
            PdfAcroForm form = PdfAcroForm.getAcroForm(doc,true);
            //匹配表单字段并填充对应的值
            Map<String, PdfFormField> fieldMap =  form.getFormFields();
            for(Map.Entry<String,String> item : data.entrySet()){
                if(fieldMap.containsKey(item.getKey())){
                    fieldMap.get(item.getKey()).setFont(font).setValue(item.getValue());
                }
            }
            //使设置生效
            form.flattenFields();
        }
    }

2.通过查询文件位置来覆盖文字

这种方法比较粗暴,直接获取原文件位置,并用背景色覆盖,再在原有位置填充新文字。但原的文字并没有消失,而是被背景色隐藏了,像变色龙。而新文字就像在上面的一个图层,若选中文字并复制,会发现复制的文字还是旧文字,而不是新文字。 代码如下:

    /**
     * 替换pdf中的文本
     * @param input 原始pdf文件输入流
     * @param data 要替换的数据
     * @param output 替换后的pdf输出流
     * @throws IOException 可能抛出的异常
     */
    public static void replaceText(InputStream input, Map<String,String> data, OutputStream output) throws IOException {
        try(PdfDocument pdfDocument = new PdfDocument(new PdfReader(input), new PdfWriter(output))){
            //遍历每一页
            int count =pdfDocument.getNumberOfPages();
            for(int i = 1; i <= count; i++){
                PdfPage page = pdfDocument.getPage(i);
                PdfCanvas pdfCanvas = new PdfCanvas(page);
                for(Map.Entry<String,String> item : data.entrySet()){
                    //查找页中的匹配文字,并定位到位置。
                    RegexBasedLocationExtractionStrategy strategy = new RegexBasedLocationExtractionStrategy(item.getKey());
                    PdfCanvasProcessor processor = new PdfCanvasProcessor(strategy);
                    processor.processPageContent(page);
                    Collection<IPdfTextLocation> locations = strategy.getResultantLocations();

                    for(IPdfTextLocation location : locations){
                        //用背景色覆盖原来的文字,其实是文字与背景同色,但文字还在。
                        pdfCanvas.saveState();
                        pdfCanvas.setFillColor(DeviceRgb.WHITE);
                        pdfCanvas.rectangle(location.getRectangle());
                        pdfCanvas.fill();
                        pdfCanvas.restoreState();
                        //在定位的位置填上替换的新文字,必须指定位置和字体,否则汉字不显示或显示在最底部。
                        pdfCanvas.beginText();
                        pdfCanvas.setTextMatrix(location.getRectangle().getX(), location.getRectangle().getY()+4);
                        pdfCanvas.setFontAndSize(getDefaultFont(),13);
                        pdfCanvas.showText(item.getValue());
                        pdfCanvas.endText();
                        //这是通过控件的方式替换文字,与上面方法效果一样。
//                        Canvas canvas = new Canvas(pdfCanvas,location.getRectangle());
//                        canvas.setFont(getDefaultFont());
//                        Text text = new Text(item.getValue());
//                        Paragraph paragraph = new Paragraph(text);
//                        canvas.add(paragraph);
//                        canvas.flush();
//                        canvas.close();
                    }
                }
            }
        }
    }

3.总结

这两种方法根据不同需求来选中,若对文档质量要求比较高,在商业领域最好使用表单模式,花钱买个pdf编辑器也是值得的;若对文档要求不高,或仅做展现,用覆盖的方法也可以解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalsonTung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值