教你怎么用Java通过关键字修改pdf

一、前言

在main方法中测试该方法,还需要引用的jar包有itextpdf-5.5.10.jar、itext-asian-5.2.0.jar
注意:两jar包之间有版本对应,否则会出现报错,该报错主要针对设置中文字体的方法
java itext 报错 com.itextpdf.text.DocumentException: Font 'STSong-Light' with 'UniGB-UCS2-H'

import com.itextpdf.text.Chunk;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @Desc
 * @Author madengling
 * @Time 2021/5/11 15:18
 */
public class UpdatePdf {

    public static void main(String[] args) {
        File file = new File("G://files//cs//111.pdf");//模拟文件位置
        if(file!=null && file.exists()){
            FileInputStream is = null;
            try {
                //本地根据文件路径获取文件流
                is = new FileInputStream(file);
                long length = file.length();
                byte[] fileBytes = new byte[(int)length];
                is.read(fileBytes);
                //进行pdf文件修改
                File file1 = pdfFzSqsj(fileBytes);
                if(file1!=null && file1.exists()){
                    System.out.println("修改pdf完成!");
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if(is!=null){
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 根据pdf的固定关键字,查找进行pdf相关位置增加文字
     * @param tpeHtcxyw 文件流
     * @return 修改后的文件
     */
    private static File pdfFzSqsj(byte[] tpeHtcxyw) {
        PdfStamper stamper = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
            //获取要写入的申请时间
            String sj  =sdf.format(new Date());
            PdfReader reader = new PdfReader(tpeHtcxyw);
            //创建文件路径
			String filePath = "G://files/cs/";
            System.out.println("filePath="+filePath);
            File directory = new File(filePath);
            //如果pdf保存路径不存在,则创建路径
            if (!directory.exists()) {
                directory.mkdirs();
            }
            String filename = UUID.randomUUID()+"_after.pdf";//修改后文件
			String filename1 = UUID.randomUUID()+"_before.pdf";//修改前文件 再输出一遍,校验自己在修改之前拿到正确的文件流
            System.out.println("file:"+filePath+filename);
            File file = new File(filePath+filename);
			File file1 = new File(filePath+filename1);
            //将写入临时文件
			FileOutputStream  foss = new FileOutputStream (file1);
			foss.write(tpeHtcxyw);
			foss.close();
            //设置字体
            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
            Font font = new Font(baseFont);
            stamper = new PdfStamper(reader, new FileOutputStream(file));
            //对于已经固话的pdf回填申请时间
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                PdfContentByte over = stamper.getOverContent(i);
                ColumnText columnText = new ColumnText(over);
                if(i==1){
                    String str = "申请日期:";
                    //根据关键字获取关键字位置
                    float[] po =  Html2Pdf.getGzzzb(str,tpeHtcxyw);
                    if(po[0]==1.00f){
                        // 方法setSimpleColumn(float llx, float lly, float urx, float ury)
                        // llx 和 urx  最小的值决定离左边的距离. lly 和 ury 最大的值决定离下边的距离
                        columnText.setSimpleColumn( po[1]+46f,  po[2]-9f, 500, 0);
                        //将时间文本创建成对象
                        Paragraph elements = new Paragraph(0, new Chunk(new Chunk(sj)));
                        // 设置字体,如果不设置添加的中文将无法显示
                        elements.setFont(font);
                        columnText.addElement(elements);
                        columnText.go();
                    }
                }
            }
            return file;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if(stamper!=null){
                try {
                    stamper.close();
                } catch (DocumentException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

二、Html2Pdf

import com.itextpdf.awt.geom.Rectangle2D;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;

public class Html2Pdf {
    /**
     * 定位pdf文件中关键字坐标
     * @param signKey 关键字
     * @param pdf 文件流
     * @return 坐标位置
     */
    public static float[] getGzzzb(String signKey, byte[] pdf){
        PdfReader reader=null;
        final float[] po = new float[3];
        try{
            reader = new PdfReader(pdf);
            int pageNum = reader.getNumberOfPages();
            final String signKeyWord = signKey;
            for(int page=1; page <= pageNum; page++){
                PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(reader);
                pdfReaderContentParser.processContent(page, new RenderListener() {
                    StringBuilder sb = new StringBuilder("");
                    int maxLength = signKeyWord.length();
                    @Override
                    public void renderText(TextRenderInfo textRenderInfo) {
                        // 只适用 单字块文档 以及 关键字整个为一个块的情况
                        // 设置 关键字文本为单独的块,不然会错位
                        boolean isKeywordChunk = textRenderInfo.getText().length() == maxLength;
                        if (isKeywordChunk) {
                            // 文档按照 块 读取
                            sb.delete(0, sb.length());
                            sb.append(textRenderInfo.getText());
                        } else {
                            // 有些文档 单字一个块的情况
                            // 拼接字符串
                            sb.append(textRenderInfo.getText());
                            // 去除首部字符串,使长度等于关键字长度
                            if (sb.length() > maxLength) {
                                sb.delete(0, sb.length() - maxLength);
                            }
                        }
                        // 判断是否匹配上
                        if (signKeyWord.equals(sb.toString())) {
                            // 计算中心点坐标
                            Rectangle2D.Float baseFloat = textRenderInfo.getBaseline()
                                    .getBoundingRectange();
                            Rectangle2D.Float ascentFloat = textRenderInfo.getAscentLine()
                                    .getBoundingRectange();
                            float centreX;
                            float centreY;
                            if (isKeywordChunk) {
                                centreX = baseFloat.x + 5*ascentFloat.width / 6;
                                centreY = baseFloat.y + (5*(ascentFloat.y - baseFloat.y) / 6);
                            } else {
                                centreX = baseFloat.x + ascentFloat.width - (5*maxLength * ascentFloat.width / 6);
                                centreY = baseFloat.y + (5*(ascentFloat.y - baseFloat.y) / 6);
                            }
                            po[0]=1.00f;
                            po[1]=centreX+3;
                            po[2]=centreY;
                            // 匹配完后 清除
                            sb.delete(0, sb.length());
                        }
                    }
                    @Override
                    public void renderImage(ImageRenderInfo arg0) {}
                    @Override
                    public void endTextBlock() {}
                    @Override
                    public void beginTextBlock() {}
                });
            }
            if(po[0]==1.00f){
                return po;
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            if(reader!=null){
                reader.close();
            }
        }
        return null;
    }

三、结果图

111.pdf是原始文件,其余两文件在方法执行后生成,before文件内容与111.pdf一致

我的原始pdf中含有关键字申请时间,修改前后文件内容如下:


到此这篇关于教你怎么用Java通过关键字修改pdf的文章就介绍到这了,更多相关关键字修改pdf内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java 在PDF中添加骑缝章示例解析

    骑缝章是用于往来业务合同,以确保合同真实.有效的印章加盖方法,是一种防范风险的重要方式.在Java程序中,可以通过使用工具来辅助加盖这种骑缝章. 工具:Free Spire.PDF for Java (免费版) 工具获取及jar文件导入: 方式1:通过官网下载jar包,并解压,手动导入lib文件夹下的Spire.Pdf.jar文件. 方式2:通过创建Maven程序,在pom.xml中配置maven仓库路径并指定Free Spire.PDF for Java 的依赖,配置完成后,在IDEA中,点击

  • Java实现图片转换PDF文件的示例代码

    最近因为一些事情,需要将一张简单的图片转换为PDF的文件格式,在网上找了一些工具,但是这些工具不是需要注册账号,就是需要下载软件. 而对于只是转换一张图片的情况下,这些操作显然是非常繁琐的,所以作者就直接使用Java写了一个图片转换PDF的系统,现在将该系统分享在这里. 引入依赖 <!--该项目以SpringBoot为基础搭建--> <parent> <groupId>org.springframework.boot</groupId> <artifa

  • java 画pdf用itext调整表格宽度、自定义各个列宽的方法

    ps:我用的版本是7.0.5 场景: 左侧第一列宽度不够,导致数据换行. Table table = new Table(new float[2]); new 一个Table之后,setWidthPercent()这个参数是这是所有列宽,并不能试用个别列. 需要在写入数据的时候对各个列进行自定义列宽: Cell cell=new Cell().setWidth(70).setBorder(Border.NO_BORDER).setHorizontalAlignment(HorizontalAli

  • Java 使用openoffice进行word转换为pdf的方法步骤

    一.下载openoffice第三方工具 建议下载4.1.6版本 http://www.openoffice.org/download/index.html 二.开启openoffice服务 找到openoffice安装目录下OpenOffice 4\program>soffice运行cmd,运行命令soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard 三.Java代

  • Java pdf和jpg互转案例

    pdfbox: jpg转pdf: /** * 使用pdfbox将jpg转成pdf * @param jpgStream jpg输入流 * @param pdfPath pdf文件存储路径 * @throws IOException IOException */ public static void jpgToPdf(InputStream jpgStream, String pdfPath) throws IOException { PDDocument pdDocument = new PDD

  • Java生成pdf文件或jpg图片的案例讲解

    在一些业务场景中,需要生成pdf文件或者jpg图片,有时候还需要带上水印.我们可以事先用freemarker定义好html模板,然后把模板转换成pdf或jpg文件. 同时freemarker模板还支持变量的定义,在使用时可以填充具体的业务数据. 1.Maven导包 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</ar

  • Java使用iTextPDF生成PDF文件的实现方法

    iText介绍和说明 因为项目需要生成PDF文件,所以去找了一下能够生成PDF的Java工具,看到了iText可以说好评如潮. 如果你想通过java操作PDF文件,那么 iText 绝对是你的首选. 引入依赖 这里使用的是iText5 <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.10</ve

  • 用Java验证pdf文件的电子章签名

    pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4

  • Java实现Word/Pdf/TXT转html的示例

    引言: 最近公司在做一个教育培训学习及在线考试的项目,本人主要从事网络课程模块,主要做课程分类,课程,课件的创建及在线学习和统计的功能,因为课件涉及到多种类型,像视频,音频,图文,外部链接及文档类型.其中就涉及到一个问题,就是文档型课件课程在网页上的展示和学习问题,因为要在线统计学习的课程,学习的人员,学习的时长,所以不能像传统做法将文档下载到本地学习,那样就不受系统控制了,所以最终的方案是,在上传文档型课件的时候,将其文件对应的转换成HTML文件,以便在网页上能够浏览学习 下边主要针对word

  • Java 实现word模板转为pdf

    1. pom相关依赖 工具poi-tl (操作word文档模板) + jacob (将操作后的word模板转为pdf) <!-- poi-tl的pom依赖 --> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.9.1</version> </dependency> <

  • 基于Java SWFTools实现把pdf转成swf

    SWF Tools 是一组用来处理 Flash 的 swf 文件的工具包,包括: 1. 合并工具 swfcombine 2. 抽取工具 swfextract 3. PDF/JPEG/PNG/AVI/TTF/WAV 到 SWF 的转换工具 :pdf2swf, jpeg2swf, png2swf, avi2swf, font2swf, and wav2swf| 4. 文本解析工具 swfstrings 5. SWF 解析器 swfdump 6. SWF 读写库 rfxswflib 1.下载swfTo

  • java 后端生成pdf模板合并单元格表格的案例

    这里只放部分片段的代码 java中使用二维数组生成表格非常方便,但是每一维的数组都需要排好序,而且,在java中所谓的二维数组,三维数组等,其实都是多个一维数组组成的 /** * 添加子女教育规划表. * @param name 子女姓名 * @param educationItems 某个孩子的教育规划的二维数组,每列依次是:学程阶段.年数.费用支出(元)/年.年增长率 * @param spacing * @throws DocumentException * @throws IOExcep

  • Java 在PDF中绘制形状的两种方法

    在我们编辑PDF文档的过程中,有时候需要在文档中添加一些如多边形.矩形.椭圆形之类的图形,而Free Spire PDF for Java 则正好可以帮助我们在Java程序中通过代码在PDF文档中绘制形状,以及设置形状边线颜色和填充色. Jar包导入 方法一:下载Free Spire.PDF for Java包并解压缩,然后将lib文件夹下的Spire.Pdf.jar包作为依赖项导入到Java应用程序中 方法二:直接通过Maven仓库安装JAR包,配置pom.xml文件的代码如下: <repos

  • java 用itext设置pdf纸张大小操作

    做快递面单打印模板,快递要求纸张大小100 x 150mm. PageSize.A4=595 x 842 A4尺寸=210mm×297mm 故设置纸张大小: public static final Rectangle EXP = new RectangleReadOnly(283.0F, 425.0F); 补充:解决iText生成pdf文件过大的问题 为iText生成的pdf文件瘦身. 原来生成pdf文件,即使是纯文本内容,无论内容再如何少,文件体积总是在7M多,导致传输速度很慢.经排查,是在p

  • Java 基于Spire.Cloud.SDK for Java在PDF中绘制形状

    Spire.Cloud.SDK for Java提供了pdfPathApi接口可用于在PDF文档中绘制形状(或图形),如绘制线条形状drawLine().绘制矩形形状drawRectanglef(),下面将介绍如何通过Java示例和步骤来实现: 一.导入jar文件.(有2种方式) 创建Maven项目程序,通过maven仓库下载导入.以IDEA为例,新建Maven项目,在pom.xml文件中配置maven仓库路径,并指定spire.cloud.sdk的依赖,如下: <repositories>

随机推荐