PDF内根据关键字插入图片

根据pdf内指定关键字的座标插入图片,实现分为两个步骤。

1:查找出dpf内所有的关键字的座标和关键字所在的页数。

2:根据查到的关键字位置出入图片;

引入

compile('com.itextpdf:itextpdf:5.5.6')
import com.itextpdf.awt.geom.Rectangle2D.Float;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
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 PDFUtil {

    // 指定关键字
    public static String KEY_WORD = "sign";
    // PDF当前页数
    public static int curPage = 0;

    /**
     * 获取指定PDF文件中指定关键字的座标
     *
     * @param fileByte
     * @return
     * @throws Exception
     */
    public static List<float[]> getKeyWordCoordinate(byte [] fileByte,String keyWord) throws ServiceException {
        // 座标信息集合
        List<float[]> arrays = new ArrayList<>();
        final int[] count = {0};
        if(keyWord.toCharArray().length < 2){
            throw new ServiceException(ErrorConstantsEnum.KEY_WORD_LENGTH_SMALL_TWO);
        }

        PdfReader pdfReader = null;
        try {
            pdfReader = new PdfReader(fileByte);
            int pageNum = pdfReader.getNumberOfPages();
            PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
            for (curPage = 1; curPage <= pageNum; curPage++) {
                pdfReaderContentParser.processContent(curPage, new RenderListener() {
                    // 关键字标志
                    boolean isKeyWord = false;
                    // PDF读出来的文字与截取关键字的第index位对比,如果在关键字的长度里
                    /**
                     * 这里从PDF中是一个一个读取文字的,把读取出来的PDF文字先和关键字的第一个字比较看是否相同:
                     * 如果相同,则假设已经找到关键字(将isKeyWord设为true),把这个关键字的座标存到集合里面,并计算集合里存放了多少个数据(count++)、设置进入到一个循环(loop
                     * = true一个循环即为关键字从第一个字到最后一个字依次和读取的PDF文字比较的过程);
                     * 如果在这个比较过程中发现有的字符和关键字不匹配,则移除与之对应的集合里的数据。
                     */
                    // 关键字的第几位
                    int index = 0;
                    // 对比关键字是否进入到一个循环
                    boolean loop = false;

                    // 处理数据
                    public void renderText(TextRenderInfo textRenderInfo) {
                        String text = textRenderInfo.getText();
                        if (text.equals(new String(keyWord.toCharArray(), 0, 1)) && text != null) {
                            // 把当前从PDF文件中读取的文字横座标、纵座标和当前页存到集合里面
                            Float boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
                            float[] resu = new float[3];
                            resu[0] = boundingRectange.x;
                            resu[1] = boundingRectange.y;
                            resu[2] = curPage;
                            arrays.add(resu);
                            count[0] = count[0] + 1;

                            isKeyWord = true;
                            loop = true;
                            return;
                        }

                        if (isKeyWord) {
                            // 获取关键字中下一个字符和读取文字比较
                            index++;

                            if (index < keyWord.toCharArray().length) {
                                if (text.equalsIgnoreCase(new String(keyWord.toCharArray(), index, 1)) && text != null) {
                                    isKeyWord = true;
                                    return;
                                } else {
                                    isKeyWord = false;
                                    // 如果在一个循环中比较时,发现有字符和关键字不匹配,则移除与之对应的集合里的数据
                                    if (loop) {
                                        count[0]--;
                                        arrays.remove(count[0]);
                                    }
                                }
                            } else {
                                // 如果index大于关键字字符数组的长度,则该循环结束
                                loop = false;
                            }
                        }

                        index = 0;
                    }

                    public void renderImage(ImageRenderInfo arg0) {

                    }

                    public void endTextBlock() {

                    }

                    public void beginTextBlock() {

                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (pdfReader != null) {
                pdfReader.close();
            }
        }

        return arrays;
    }

测试方法:

 //测试
    public static void main(String[] args) throws Exception {
        String pdfname = "D:\\目标PDF.pdf";
        List<float[]> list = getKeyWordCoordinate(IOUtils.toByteArray(new FileInputStream(pdfname)),"sign");
        PdfReader pdfReader = new PdfReader(new FileInputStream(pdfname));
        PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream("D://test/插入图片后的PDF.pdf"));

        for (float[] f : list) {
            System.out.println("x座标:" + f[0] + ",y座标:" + f[1] + ", 关键字所在页:" + f[2]);
            // 读图片
            Image image = Image.getInstance("D:\\MyData/java虚拟机内存图.jpg");
            // 获取操作的页面
            PdfContentByte under = pdfStamper.getOverContent((int)f[2]);
            // 根据域的大小缩放图片
            image.scaleAbsolute(100, 50);
            // 添加图片
            image.setAbsolutePosition((int) f[0], (int) f[1]);
            under.addImage(image);

        }
        
   
        pdfStamper.close();
        pdfReader.close();
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章