zoukankan      html  css  js  c++  java
  • 生成 PDF 全攻略【2】在已有PDF上添加内容

      项目在变,需求在变,不变的永远是敲击键盘的程序员.....

         PDF 生成后,有时候需要在PDF上面添加一些其他的内容,比如文字,图片....

         经历几次失败的尝试,终于获取到了正确的代码书写方式。

         在此记录总结,方便下次以不变应万变,需要的 jar 请移步:生成PDF全攻略

            PdfReader reader = new PdfReader("E:\A.pdf");
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("E:\B.pdf"));
            PdfContentByte overContent = stamper.getOverContent(1);

        上述的这段代码算是在原有 PDF 上面添加内容的核心代码,具体流程如下

    • 如果看官老爷够仔细的话,该代码是将原 A.pdf 读取,然后将它写入 B.pdf,然后操作 B.pdf。
    • 可能有的看官老爷会说,将 A 读取,然后在写入 A 中,这样肯定是不行的,在读取的时候 A 已经被加载了,不能进行修改。
    • 我不喜欢这种方式,因为原 PDF 的信息已经存储在数据库中,其中包括 PDF 的服务器路径、旧名称、新名称、类型......
    • 这样就会多出一次数据库变更操作,因为这里PDF名称需要变更,而且鬼知道后续需求还会怎么变。
    • 这里急需 只在 PDF 中添加内容,其他的什么都不变,将代码稍微调整了一下。
    复制代码
            FileUtil.fileChannelCopy(A.pdf,A + "tmp".pdf));
            PdfReader reader = new PdfReader(A + "tmp".pdf);
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(A.pdf));
            PdfContentByte overContent = stamper.getOverContent(1);
    复制代码

        代码流程就变做下面这个样子

    • 这里引入了管道复制文件,将A 复制一份,读取副本,然后写回到原 PDF A 中,最后当然需要删除副本文件。
    • 到这里,无论后续需求怎么变,保证了pdf 的其他属性不变,就能从容面对。

         管道复制代码如下:

    复制代码
        public static void fileChannelCopy(File sources, File dest) {
            try {
                FileInputStream inputStream = new FileInputStream(sources);
                FileOutputStream outputStream = new FileOutputStream(dest);
                FileChannel fileChannelin = inputStream.getChannel();//得到对应的文件通道
                FileChannel fileChannelout = outputStream.getChannel();//得到对应的文件通道
                fileChannelin.transferTo(0, fileChannelin.size(), fileChannelout);//连接两个通道,并且从in通道读取,然后写入out通道
    
                inputStream.close();
                fileChannelin.close();
                outputStream.close();
                fileChannelout.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    复制代码

          完整的在已有PDF添加其他内容代码如下:

    复制代码
            FileUtil.fileChannelCopy(new File("E:\A.pdf"),new File("E:\A+"tmp".pdf"));
            PdfReader reader = new PdfReader("E:\A+"tmp".pdf");
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("E:\A.pdf"));
            PdfContentByte overContent = stamper.getOverContent(1);
    
            //添加文字
            BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            overContent.beginText();
            overContent.setFontAndSize(font, 10);
            overContent.setTextMatrix(200, 200);
            overContent.showTextAligned(Element.ALIGN_CENTER,"需要添加的文字",580,530,0);
            overContent.endText();
    
            //添加图片
            PdfDictionary pdfDictionary = reader.getPageN(1);
            PdfObject pdfObject =  pdfDictionary.get(new PdfName("MediaBox"));
            PdfArray pdfArray = (PdfArray) pdfObject;
            Image image = Image.getInstance("D:\1.jpg");
            image.setAbsolutePosition(100,100);
            overContent.addImage(image);
    
            //添加一个红圈
            overContent.setRGBColorStroke(0xFF, 0x00, 0x00);
            overContent.setLineWidth(5f);
            overContent.ellipse(250, 450, 350, 550);
            overContent.stroke();
            stamper.close();
  • 相关阅读:
    Silverlight 自定义表格 转
    Application_BeginRequest事件过滤恶意提交
    存储过程学习1
    我是博客园新博客
    努力将SQL Server像玩游戏一样熟练
    【Demo 0003】支持交互的应用
    【Demo 0003】支持交互的应用
    linux终端快捷键
    vim与windows/linux之间的复制粘贴小结
    vimgrep简单使用
  • 原文地址:https://www.cnblogs.com/zhengxingpeng/p/6674825.html
Copyright © 2011-2022 走看看