首页 文章

某些pdf文件水印不会显示使用iText

提问于
浏览
3

我们公司使用iText在一些pdf表格上标记一些水印文本(不是图像) . 我注意到95%的表格正确显示水印,约5%没有 . 我测试了,复制了2个原始pdf文件,一个标记为ok,另一个没有问题,然后通过一个小程序进行测试,结果相同:一个得到标记,另一个没有 . 然后我尝试了最新版本的iText jar文件(版本5.0.6),同样的事情 . 我检查了pdf文件属性,安全设置等,似乎没有显示任何提示 . 结果文件确实改变了大小,并在执行程序后标记为“由iText版本改变....” .

这是样本水印代码(使用itext jar版本2.1.7),注意传入的topText,mainText,bottonText参数,使3行水印在pdf中显示为水印 .

任何帮助赞赏!!

public class WatermarkGenerator {

    private static int TEXT_TILT_ANGLE = 25;
    private static Color MEDIUM_GRAY = new Color(160, 160, 160);
    private static int SUPPORT_FONT_SIZE = 42;
    private static int PRIMARY_FONT_SIZE = 54;

    public static void addWaterMark(InputStream pdfInputStream,
        OutputStream outputStream, String topText, 
        String mainText, String bottomText) throws Exception {
        PdfReader reader = new PdfReader(pdfInputStream);
        int numPages = reader.getNumberOfPages();

        // Create a stamper that will copy the document to the output
        // stream.
        PdfStamper stamp = new PdfStamper(reader, outputStream);
        int page=1;

        BaseFont baseFont = 
            BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE,
                BaseFont.WINANSI, BaseFont.EMBEDDED);

        float width;
        float height;

        while (page <= numPages) {
            PdfContentByte cb = stamp.getOverContent(page);
            height = reader.getPageSizeWithRotation(page).getHeight() / 2;
            width = reader.getPageSizeWithRotation(page).getWidth() / 2;

            cb = stamp.getUnderContent(page);
            cb.saveState();
            cb.setColorFill(MEDIUM_GRAY);

            // Top Text
            cb.beginText();
            cb.setFontAndSize(baseFont, SUPPORT_FONT_SIZE);
            cb.showTextAligned(Element.ALIGN_CENTER, topText, width,
                    height+PRIMARY_FONT_SIZE+16, TEXT_TILT_ANGLE);
            cb.endText();

            // Primary Text
            cb.beginText();
            cb.setFontAndSize(baseFont, PRIMARY_FONT_SIZE);
            cb.showTextAligned(Element.ALIGN_CENTER, mainText, width,
                    height, TEXT_TILT_ANGLE);
            cb.endText();

            // Bottom Text
            cb.beginText();
            cb.setFontAndSize(baseFont, SUPPORT_FONT_SIZE);
            cb.showTextAligned(Element.ALIGN_CENTER, bottomText, width,
                    height-PRIMARY_FONT_SIZE-6, TEXT_TILT_ANGLE);
            cb.endText();
            cb.restoreState();

            page++;
        }

        stamp.close();
    }
}

2 回答

  • 1

    我们通过更改Adobe LifecycleSave文件选项解决了问题 . 文件 - >保存 - >属性 - >另存为,然后查看另存为类型,默认为Acrobat 7.0.5动态PDF表单文件,我们更改为使用7.0.5静态PDF表单文件(实际上任何静态的都可以工作) . 保存在静态文件中的文件没有此水印消失问题 . 感谢Mark指出了正确的方向 .

  • 2

    你正在使用underContent而不是overContent . 不要那样做 . 它让你受到大白色矩形的摆布,一些人坚持要先画一些东西 . 这是一个不太好的PostScript解释器,并且多年来一直没有必要 .


    好的,看过你的PDF后,我发现问题在于这是一个基于XFA的表格(来自LiveCycle Designer) . Acrobat可以(并且经常)根据它包含的XFA(一种xml)重建整个文件 . 这就是你的改变丢失的方式 . 当Acrobat从XFA重建PDF时,所有现有的PDF信息都会被调整,包括您的水印 .

    实现此功能的唯一方法是将水印定义为PDF中包含的XFA文件的一部分 .

    检测这些形式并不是那么难:

    PdfReader reader = new PdfReader(...);
    AcroFields acFields = reader.getAcroFields();
    XfaForm xfaForm = acFields.getXfaForm();
    if (xfaForm != null && xfaForm.isXfaPresent()) {
      // Ohs nose.
      throw new ItsATrapException("We can't repel XML of that magnitude!");
    }
    

    另一方面,修改它们可能是相当具有挑战性的,但是here's the specs .

    一旦你完成了XML操作的简单问题......但是"figure it out"部分可能很有趣 .

    好狩猎 .

相关问题