Некоторые водяные знаки PDF-файла не отображаются с помощью iText - PullRequest
3 голосов
/ 11 марта 2011

Наша компания использует iText для печати текста с водяными знаками (не изображения) на некоторых PDF-формах. Я заметил, что 95% форм показывает водяной знак правильно, около 5% - нет. Я проверил, скопировал 2 оригинальных pdf файла, один был помечен нормально, другой не хорошо, затем протестирован с помощью небольшой программы, тот же результат: один был помечен, другой нет. Затем я попробовал последнюю версию файла jar iText (версия 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 ]

2 голосов
/ 15 марта 2011

Мы решили проблему, изменив опцию файла Adobe LifecycleSave. File-> Save-> properties-> Save as, затем посмотрите на Save as type, по умолчанию используется Acrobat 7.0.5 Dynamic PDF Form File, мы перешли на использование 7.0.5 Static PDF Form File (фактически любой статический файл будет работать). Файл, сохраненный в статическом, не имеет этой проблемы исчезновения водяного знака. Спасибо Марк за указание в правильном направлении.

1 голос
/ 12 марта 2011

Вы используете underContent, а не overContent. Не делай этого. Это оставляет вас во власти больших белых прямоугольников, которые некоторые люди настаивают на том, чтобы рисовать первым делом. Это удержание от менее чем хороших интерпретаторов PostScript и не было необходимости в течение многих лет.


Хорошо, просмотрев ваш PDF, я вижу проблему в том, что это форма на основе XFA (из LiveCycle Designer). Acrobat может (и часто делает) перестроить весь файл на основе XFA (тип xml), который он содержит. Вот как ваши изменения теряются. Когда Acrobat перестраивает PDF из XFA, передается вся существующая информация PDF, включая ваш водяной знак.

Единственный способ заставить это работать - определить водяной знак как часть файла XFA, содержащегося в PDF.

Найти эти формы не так уж и сложно:

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!");
}

Изменение их с другой стороны может быть довольно сложным, но вот спецификации .

Как только вы выяснили, что нужно изменить, это простой вопрос манипуляции с XML ... но эта часть "выяснить это" может быть интересной .

Удачной охоты.

...