批量处理PDF内容修改

概要

记录一个批量PDF修改的功能,搜索一般是PDF遮罩层、不太符合所需要的业务逻辑,特此提供另一种思路、适用于PDF格式不复杂的。

注意pdf转换成html可能会丢失某些样式。

整体架构流程

1、把pdf通过Spire.PDF for Java 的  PDF 转为 HTML

2、读取HTML成字符串并内容替换及调整文字距离X轴、Y轴的距离

4、通过itextpdf 把html变成pdf或者通过浏览器打印变成pdf

技术细节

  用到的jar包

 <dependency>
     <groupId>com.itextpdf</groupId>
     <artifactId>itextpdf</artifactId>
     <version>5.5.13</version>
 </dependency>
 
 <dependency>
      <groupId>com.itextpdf</groupId>
      <artifactId>html2pdf</artifactId>
      <version>5.0.1</version>
 </dependency>

 <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>5.8.16</version>
 </dependency>

 <dependency>
      <groupId>e-iceblue</groupId>
      <artifactId>spire.doc</artifactId>
      <version>11.7.0</version>
 </dependency>

测试代码

package com.ruoyi.project.demo.controller;

import cn.hutool.core.io.FileUtil;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;

import java.io.FileOutputStream;

import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.spire.pdf.FileFormat;
import com.spire.pdf.PdfDocument;


public class PdfUpdate {

    public static void main(String[] args) throws Exception {
        //创建PdfDocument的对象
        PdfDocument pdf = new PdfDocument();
        //加载PDF文件
        pdf.loadFromFile("C:\\Users\\dell\\Desktop\\测试.pdf");
        //将PDF文件保存为HTML文件
        pdf.saveToFile("D:/PDFToHTML.html", FileFormat.HTML);
        pdf.close();

        String html = FileUtil.readUtf8String("D:/PDFToHTML.html");
        //删除标记
        html = html.replace("<text style=\"fill:#ff0000;font-family:Times New Roman;\" font-size=\"10\" xml:space=\"preserve\" x=\"20\" y=\"20\">Evaluation Warning : The document was created with Spire.PDF for java.</text>", "");
        //删除字符
        html = html.replace("<text style=\"fill:#000000;font-family:FF0;font-weight:bold;\" font-size=\"56\" x=\"241.426\" y=\"286.662\">检</text>", "");
        html = html.replace("<text style=\"fill:#000000;font-family:FF0;font-weight:bold;\" font-size=\"56\" x=\"297.65\" y=\"286.662\">测</text>", "");
        //调整位置
        html = html.replace("<text style=\"fill:#000000;font-family:FF0;font-weight:bold;\" font-size=\"56\" x=\"185.202\" y=\"286.662\">",
               "<text style=\"fill:#000000;font-family:FF0;font-weight:bold;\" font-size=\"56\" x=\"225.202\" y=\"286.662\">");
        html = html.replace("<text style=\"fill:#000000;font-family:FF0;font-weight:bold;\" font-size=\"56\" x=\"353.874\" y=\"286.662\">",
               "<text style=\"fill:#000000;font-family:FF0;font-weight:bold;\" font-size=\"56\" x=\"323.874\" y=\"286.662\">");
        html = html.replace("<title>PDFToHTML</title>","<title></title>");

       for (int i = 5; i < 100; i += 6) {
          //删除
          html = html.replace("<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"279.028\" y=\"98.83795\">检</text>", "");
          html = html.replace("<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"297.1\" y=\"98.83795\">测</text>", "");
          //后移
          html = html.replace("<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"242.884\" y=\"98.83795\">",
                   "<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"257.17203\" y=\"98.83795\">");
          html = html.replace("<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"260.956\" y=\"98.83795\">",
                   "<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"275.24402\" y=\"98.83795\">");
          //前移
          html = html.replace("<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"315.17203\" y=\"98.83795\">",
                  "<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"295.17203\" y=\"98.83795\">");
          html = html.replace("<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"333.24402\" y=\"98.83795\">",
                  "<text style=\"fill:#000000;font-family:FF" + i + ";font-weight:bold;\" font-size=\"18\" x=\"313.24402\" y=\"98.83795\">");
       }
       //如果用浏览器打印就生成新的html
       FileUtil.writeString(html, "D:/newHtml.html","utf-8");
       //直接生成pdf
       createPdf(html);
    }

    /**
     * 生成pdf并增加pdf编辑加密
     * @param html
     * @throws Exception
     */
    public static void createPdf(String html) throws Exception{
        String file = "D:/test.pdf";
        // 创建一个输出流
        FileOutputStream baos = new FileOutputStream(file);
        ConverterProperties converterProperties = new ConverterProperties();
        DefaultFontProvider fontProvider = new DefaultFontProvider(false,
                false,false);
        //增加中文字体、否则中文不显示
        fontProvider.addFont("C:/Windows/Fonts/simsun.ttc,0");
        converterProperties.setFontProvider(fontProvider);
        HtmlConverter.convertToPdf(html, baos, converterProperties);

        //加密处理
        encryption(file);
    }

    /**
     * 增加pdf编辑加密
     * @param filePath
     * @throws Exception
     */
    public static void encryption(String filePath) throws Exception{
        // 加密后的PDF 文件路径
        String destPdf = "D:/dest.pdf";
        // 加密密钥
        String password = "123456";
        // 创建 PDF 读取器
        PdfReader reader = new PdfReader(filePath);
        // 创建 PDF 写入器
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPdf));
        // 处理 PDF 文档的权限、参数1打开加密、参数2编辑加密
        stamper.setEncryption(null, password.getBytes(), PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY, PdfWriter.ENCRYPTION_AES_128);
        // 关闭 PDF 文档
        stamper.close();
        reader.close();
    }
}

效果图

处理前:

处理后:

 html中的文本格式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值