Добавление текста номера страницы в копию PDF переворачивается / отражается с помощью itext 7 - PullRequest
0 голосов
/ 10 октября 2018

Итак ... Я пытался использовать пример, приведенный в документации к itext, для объединения документов и создания оглавления для объединенного результата.Но часть, которая добавляет текст номера страницы на каждую страницу, не работает, как я ожидал.Что происходит, так это то, что добавленный текст переворачивается по некоторой горизонтальной оси, как показано на следующем рисунке:

enter image description here

Кроме того, документ Java для метода, используемого для установки фиксированной позиции надобавленный текст (public T setFixedPosition(int pageNumber, float left, float bottom, float width)) не имеет смысла для меня:

Устанавливает значения для абсолютного изменения положения элемента.Указанные координаты соответствуют левому нижнему углу элемента, и он увеличивается вверх.

Но когда я запускаю setFixedPosition(pageNumber, 0, 0, 50), текст попадает в верхний левый угол, снова также переворачивается.И если я использую ширину и высоту от размера страницы исходного PdfDocument в качестве параметров для левой и нижней позиций соответственно, то он даже не достигает нижнего правого угла.

Я могу сделать что-то не так или неправильно понять что-то.В любом случае, вот код, который я использую:

private static int copyPdfPages(PdfDocument source, Document document, Integer start, Integer pages, Integer number) {
    int oldC;
    int max = start + pages - 1;
    Text text;
    for (oldC = start; oldC <= max; oldC++) {
        text = new Text(String.format("Page %d", number));
        PageSize pageSize = source.getDefaultPageSize();
        source.copyPagesTo(oldC, oldC, document.getPdfDocument());
        document.add(new Paragraph(text).setBorder(new SolidBorder(ColorConstants.RED, 1))
                .setFixedPosition(number++, pageSize.getWidth() - 55, pageSize.getHeight() - 30, 50));
    }
    return oldC - start;
}

public static void main(String[] args) throws IOException {
    String path = "/path/to/target";

    FileOutputStream fos = new FileOutputStream(path);
    PdfDocument pdfDocTgt = new PdfDocument(new PdfWriter(fos));
    Document document = new Document(pdfDocTgt);

    PdfDocument pdfDocSrc = new PdfDocument(new PdfReader(new FileInputStream("path/to/source")));

    copyPdfPages(pdfDocSrc, document, 1, pdfDocSrc.getNumberOfPages(), 1);

    pdfDocTgt.close();
    pdfDocSrc.close();
    document.flush();
    document.flush();
    fos.flush();
    fos.close();
}

И вот источник в формате pdf: https://drive.google.com/open?id=11_9ptuoRqS91hI3fDcs2FRsIUEiX0a84

Помогите пожалуйста (и извините за мой английский).

1 Ответ

0 голосов
/ 11 октября 2018

Проблема

Проблема заключается в том, что Document.add предполагает, что инструкции в текущем содержимом текущей страницы в ее конце имеют графическое состояние, по существу, восстановленное до исходного состояния (или что эффектыразличия в выводе желательны).

В вашем примере PDF это предположение не выполняется, в частности инструкции по содержанию страницы начинаются с

0.750000 0.000000 0.000000 -0.750000 0.000000 841.920044 cm

, что изменяет текущую матрицу преобразования на

  • масштабирует все до 75%, а
  • переворачивает систему координат по вертикали.

При первом изменении ваше добавление не будет находиться в углу страницы, новместо этого вместо этого где-то больше к центру;последнее заставляет его зеркально отображаться вертикально и больше вниз, а не вверху страницы.

Исправление

Если не известно, является ли текущее содержимоестраница имеет в основном восстановленное графическое состояние в конце (обычно в случае, если кто-то обрабатывает содержимое страницы, сгенерированное , а не ), следует воздерживаться от добавления контента через экземпляр Document, но вместо этого использовать PdfCanvas генерируется с помощью конструктора, который оборачивает содержимое текущей страницы в состояние save-graphics ... restore-graphics-state envelop.

Например, для вашей задачи:

private static int copyPdfPagesFixed(PdfDocument source, PdfDocument target, int start, int pages, int number) {
    int oldC;
    int max = start + pages - 1;
    Text text;
    for (oldC = start; oldC <= max; oldC++) {
        text = new Text(String.format("Page %d", number));
        source.copyPagesTo(oldC, oldC, target);
        PdfPage newPage = target.getLastPage();
        Rectangle pageSize = newPage.getCropBox();
        try (   Canvas canvas = new Canvas(new PdfCanvas(newPage, true), target, pageSize)  ) {
            canvas.add(new Paragraph(text).setBorder(new SolidBorder(ColorConstants.RED, 1))
                  .setFixedPosition(number++, pageSize.getWidth() - 55, pageSize.getHeight() - 30, 50));
        }
    }
    return oldC - start;
}

( AddPagenumberToCopy метод)

Используемый выше конструктор PdfCanvas задокументирован как

/**
 * Convenience method for fast PdfCanvas creation by a certain page.
 *
 * @param page           page to create canvas from.
 * @param wrapOldContent true to wrap all old content streams into q/Q operators so that the state of old
 *                       content streams would not affect the new one
 */
public PdfCanvas(PdfPage page, boolean wrapOldContent)

Используется вот так

try (   PdfDocument pdfDocSrc = new PdfDocument(new PdfReader(SOURCE));
        PdfDocument pdfDocTgt = new PdfDocument(new PdfWriter(TARGET))    ) {
    copyPdfPagesFixed(pdfDocSrc, pdfDocTgt, 1, pdfDocSrc.getNumberOfPages(), 1);
}

( AddPagenumberToCopy test testLikeAibanezFixed)

верх первой страницы результатов выглядит следующим образом:

screen shot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...