Как добавить несколько текстовых полей на одной или нескольких страницах в цикле - PullRequest
0 голосов
/ 30 января 2019

Я использую Itext 5 maven, и я хочу добавить несколько текстовых полей на нескольких страницах PDF.как на странице 1 нужно 3 поля, на странице 2 нужно 4 поля и т. д.

Я написал следующий код:

public byte[] setupDocument(EditPdfDTO editPdfDTOList, MultipartFile attachment)
{

    WritePDF obj = new WritePDF();

    Document document = null;
    PdfWriter writer = null;
    PdfImportedPage page = null;
    PdfReader reader = null;
    try
    {
        // Create output PDF
        document = new Document(PageSize.A4);
        document.setMargins(0, 0, 0, 0);

        writer = PdfWriter.getInstance(document,
                new FileOutputStream("D:/test.pdf"));

        document.open();
        PdfContentByte cb = writer.getDirectContent();

        // Load existing PDF
        reader = new PdfReader(attachment.getBytes());

        int totalPages = reader.getNumberOfPages();
        for (int i = 0; i < totalPages; i++)
        {
            page = writer.getImportedPage(reader, i + 1);
            document.newPage();
            cb.addTemplate(page, 0, 0);

            for (int j = 0; j < editPdfDTOList.getPdf().size(); j++)
            {
                if (i + 1 == editPdfDTOList.getPdf().get(j).getPageNo())
                {
                    BaseFont baseFont = null;
                    try
                    {
                        baseFont = BaseFont.createFont();
                    }
                    catch (DocumentException | IOException e1)
                    {
                        e1.printStackTrace();
                    }

                    int a, b;
                    a = editPdfDTOList.getPdf().get(j).getxCoordinate();
                    b = editPdfDTOList.getPdf().get(j).getyCoordinate();

                    String str = editPdfDTOList.getPdf().get(j).getTextContent();

                    Rectangle linkLocation =
                            new Rectangle(a, b + baseFont.getDescentPoint(str, 10),
                                    a + 10 + baseFont.getWidthPoint(str, 10),
                                    b + baseFont.getAscentPoint(str, 10) + 10);
                    TextField field =
                            new TextField(writer, linkLocation, "user1" + j+UUID.randomUUID());

                    field.setFontSize(10);
                    field.setOptions(TextField.MULTILINE | TextField.READ_ONLY);
                    field.setTextColor(BaseColor.RED);
                    field.setText(str);
                    field.setBorderWidth(1);

                    cb = writer.getDirectContent();

                    try
                    {
                        cb.addAnnotation(field.getTextField(),false);
                    }
                    catch (IOException | DocumentException e)
                    {
                         e.printStackTrace();           
                    }

                }
            }
        }
    }
    catch (DocumentException | IOException e)
    {
        e.printStackTrace();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    finally
    {
        document.close();

    }
    return null;
}

этот код может добавлять только одно текстовое поле в каждое ожидаемое, но не вдобавьте 2 или несколько текстовых полей на одной странице.

нет проблем с множеством блоков try - catch.

1 Ответ

0 голосов
/ 30 января 2019

Подходящие классы для использования

Прежде всего, вы говорите, что "хотите добавить несколько текстовых полей на нескольких страницах PDF" .При реализации подобных задач, то есть задач, которые берут один документ и хотят каким-то образом манипулировать им, сохраняя его более или менее структурно, как раньше, обычно следует работать с парой PdfReader / PdfStamper.Это позволяет вам сконцентрироваться на манипуляции и предоставляет копию исходного PDF со всеми его свойствами для работы.

Добавление нескольких полей на страницу существующего PDF

Добавление нескольких полей водна существующая страница тривиальна, например:

PdfReader pdfReader = new PdfReader(resource);
PdfStamper pdfStamper = new PdfStamper(pdfReader, output);

TextField field1 = new TextField(pdfStamper.getWriter(),
                                 new Rectangle(100, 800, 200, 820), "Field1");
field1.setBorderColor(BaseColor.CYAN);
field1.setBorderStyle(PdfBorderDictionary.STYLE_DASHED);
field1.setBorderWidth(BaseField.BORDER_WIDTH_MEDIUM);
field1.setText("Field 1");
pdfStamper.addAnnotation(field1.getTextField(), 1);

TextField field2 = new TextField(pdfStamper.getWriter(),
                                 new Rectangle(300, 800, 400, 820), "Field2");
field2.setBorderColor(BaseColor.RED);
field2.setBorderStyle(PdfBorderDictionary.STYLE_INSET);
field2.setBorderWidth(BaseField.BORDER_WIDTH_THIN);
field2.setText("Field 2");
pdfStamper.addAnnotation(field2.getTextField(), 1);

pdfStamper.close();

( AddField test testAddMultipleFields)

Применимо к моему примеру документа

screen shot original

код генерирует

screen shot result

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

В вашем случае я бы переключился на использование пары PdfReader / PdfStamper.Если какая-то проблема все еще остается, я проверю ваши данные.Возможно, они просто содержат только один набор данных поля на страницу.Или два текстовых поля имеют одинаковые координаты и, следовательно, выглядят как одно.Или некоторые текстовые поля имеют внеэкранные координаты.Или ... Или ... Или ...

Оригинальный ответ

Изначально код в вопросе выглядел иначе.Этот оригинальный ответ сфокусирован на проблемах этого кода.

Вы утверждаете, что ваш код

может добавлять только одно текстовое поле в каждое ожидаемое, но не добавлять 2 или несколько текстовых полейна одной странице

Я сомневаюсь, что, поскольку

  1. у вас есть два разных объекта, одновременно записывающих в один файл "D:/TemplateFilePDf/" + attachment.getOriginalFilename(), PdfWriter writer иPdfStamper stamper.Если вы получаете что-то разумное в результате вашего кода, то только по счастливой случайности;и

  2. дополнительно stamper создается для null экземпляра PdfReader.Это на самом деле вызовет NullPointerException в конструкторе, который будет препятствовать тому, чтобы ваше текстовое поле добавляло код от выполнения вообще.

Таким образом, либо код, которым вы поделились, значительно отличается от кода, который вывыполнить или ваш тестовый запуск фактически все выдает это NullPointerException, и вы, вероятно, найдете результаты предыдущей, менее испорченной версии вашего кода, которая, как оказалось, добавила только одно текстовое поле.

После исправления этих двух проблемнекоторые вопросы все еще остаются (например, какова цель этого cb.fill()? Эта инструкция разрешена только после определения пути, пути, внутренняя область которого должна быть заполнена, но я не вижу, чтобы вы определяли какой-либо путь).

Кроме того, вы получаете доступ к вашему editPdfDTOList для множества соответствующих значений, но мы не знаем эти значения.Таким образом, мы не можем запустить ваш код, чтобы попытаться воспроизвести проблему.Возможно, вы создаете только одно текстовое поле, потому что этот объект содержит только значения для одного текстового поля ...

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