Создайте таблицу с повторяющимся заголовком с помощью iText

Я хочу создать таблицу с повторяющимися заголовками, как изображение, которое я прикрепил к своему сообщению.

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

Я использовал одну таблицу с 6 столбцами, как показано на странице. Я получил данные из базы данных в соответствии с порядком дат, и я хочу разместить свои данные в таблице, как на картинке.

Я могу создать таблицу с помощью iText в java, но я не знаю, как создать таблицу с этим стилем с помощью iText. пожалуйста, помогите мне, если это возможно.

Создайте таблицу с повторяющимся заголовком с помощью iText

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
1 278
2

Ответы 2

Это относительно просто.

Сначала я создал класс, представляющий одну запись данных.

static class Record{
    public String firstname;
    public String lastname;
    public Record(String firstname, String lastname){
        this.firstname = firstname;
        this.lastname = lastname;
    }
    public String getFirstname(){return firstname;}
    public String getLastname(){return lastname;}
    public boolean equals(Object o){
        if (o instanceof Record){
            Record r = (Record) o;
            return r.firstname.equals(firstname) && r.lastname.equals(lastname);
        }
        return false;
    }
}

Я также создал метод, который случайным образом генерирует подобные объекты, используя персонажей Симпсонов.

private static Random RANDOM = new Random(System.currentTimeMillis());
public Record randomRecord(){
    String[] fn = {"Marge", "Homer", "Bart", "Lisa", "Nelson", "Apu", "Doris", "Seymour"};
    String[] ln = {"Bouvier", "Simpson", "Muntz", "Nahasapeemapetilan", "Skinner"};
    return new Record(fn[RANDOM.nextInt(fn.length)], ln[RANDOM.nextInt(ln.length)]);
}

Код для создания таблицы выглядит так:

    List<Record> recordList = new ArrayList<>();
    for(int i=0;i<17;i++)
        recordList.add(randomRecord());

    File outputFile = getOutputFile();
    PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outputFile));
    Document layoutDocument = new Document(pdfDocument);

    int numberOfItemsInFirstHalf = (int) Math.ceil(recordList.size() / 2.0);

    Table table = new Table(new float[]{0.16f, 0.16f, 0.16f, 0.16f, 0.16f, 0.16f});

    // header
    for(int i=0;i<2;i++) {
        table.addCell(new Cell().add(new Paragraph("Number")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addCell(new Cell().add(new Paragraph("Firstname")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addCell(new Cell().add(new Paragraph("Lastname")).setBackgroundColor(new DeviceRgb(74,189,172)));
    }

    // table
    for(int i=0;i<numberOfItemsInFirstHalf;i++){
        Record r0 = recordList.get(i);
        Record r1 = (i+numberOfItemsInFirstHalf) < recordList.size() ? recordList.get(i + numberOfItemsInFirstHalf) : null;

        table.addCell(new Cell().add(new Paragraph((i + 1)+"")));
        table.addCell(new Cell().add(new Paragraph(r0.getFirstname())));
        table.addCell(new Cell().add(new Paragraph(r0.getLastname())));

        if (r1 == null){
            table.addCell(new Cell().add(new Paragraph("")));
            table.addCell(new Cell().add(new Paragraph("")));
            table.addCell(new Cell().add(new Paragraph("")));
        }else{
            table.addCell(new Cell().add(new Paragraph((i + numberOfItemsInFirstHalf + 1)+"")));
            table.addCell(new Cell().add(new Paragraph(r1.getFirstname())));
            table.addCell(new Cell().add(new Paragraph(r1.getLastname())));
        }
    }

    layoutDocument.add(table);

    pdfDocument.close();

который создает следующий PDF-документ:

Большое спасибо за ответ. Я проверил ваш код, но результат не соответствует моему запросу. например, если у меня есть 250 записей, записи разделены на две страницы, и номера расположены друг под другом, а не рядом друг с другом. На первой странице последнее число - 53, а первое число второй страницы - 54, и это неверно. Я хочу, чтобы на первой странице была 54-я запись, сразу после 53 во вторых трех столбцах справа.

Sameer 29.05.2018 08:49

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

Joris Schellekens 29.05.2018 08:54

Спасибо. Есть ли способ узнать, где разбита таблица?

Sameer 29.05.2018 09:59

При добавлении элемента IE в документ вы можете запросить у средства визуализации его дочерние элементы. Если таблица разделена, вы ожидаете увидеть SplitRenderer.

Joris Schellekens 29.05.2018 10:03

Я поискал в сети, но не смог найти ни одного примера, который используется SplitRenderer. Я новичок, и до сих пор я использовал простую структуру iText, поэтому я ничего не знаю о SplitRenderer, но я стараюсь изо всех сил. Большое спасибо.

Sameer 29.05.2018 10:51

Я не совсем понял, как вы хотите, чтобы ваша таблица обрабатывалась при разделении, и предположил, что вы ищете макет из двух столбцов. В этом случае для вас есть предопределенный класс ColumnDocumentRenderer. Если установлено в экземпляре документа, это позволяет размещать содержимое документа в столбцы.

Итак, я определил столбцы:

Rectangle pageSize = pdfDocument.getDefaultPageSize(); Rectangle[] areas = new Rectangle[2]; areas[0] = new Rectangle(36, 36, ((float) pageSize.getWidth() / 2) - 35.75f, pageSize.getHeight() - 72); areas[1] = new Rectangle((float) pageSize.getWidth() / 2 - 0.25f, 36, ((float) pageSize.getWidth() / 2) - 35.75f , pageSize.getHeight() - 72);

Затем я применил средство визуализации к экземпляру документа: layoutDocument.setRenderer(new ColumnDocumentRenderer(layoutDocument, areas));

Результат на разделении выглядит так:

Полный код:

    @Test
public void tableTest02() throws Exception {
    String outFileName = destinationFolder + "tableTest02.pdf";
    String cmpFileName = sourceFolder + "cmp_tableTest02.pdf";

    PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
    Document layoutDocument = new Document(pdfDocument);


    Table table = new Table(3);
    table.setWidth(UnitValue.createPercentValue(100));

    Rectangle pageSize = pdfDocument.getDefaultPageSize();
    Rectangle[] areas = new Rectangle[2];
    areas[0] = new Rectangle(36, 36, ((float) pageSize.getWidth() / 2) - 35.75f, pageSize.getHeight() - 72);
    areas[1] = new Rectangle((float) pageSize.getWidth() / 2 - 0.25f, 36, ((float) pageSize.getWidth() / 2) - 35.75f , pageSize.getHeight() - 72);

    layoutDocument.setRenderer(new ColumnDocumentRenderer(layoutDocument, areas));
    // header
    for(int i=0;i<1;i++) {
        table.addHeaderCell(new Cell().add(new Paragraph("Number")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addHeaderCell(new Cell().add(new Paragraph("Firstname")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addHeaderCell(new Cell().add(new Paragraph("Lastname")).setBackgroundColor(new DeviceRgb(74,189,172)));
    }

    // table
    for(int i=0;i<500;i++){

        table.addCell(new Cell().add(new Paragraph((i + 1)+"")));
        table.addCell(new Cell().add(new Paragraph("Hello")));
        table.addCell(new Cell().add(new Paragraph("World")));

    }

    layoutDocument.add(table);

    pdfDocument.close();

    Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
}

Сложным моментом было свернуть границы таблицы, но, увеличив ширину на 0,25f и переместив правый столбец на 0,25f влево, я добился того, чтобы границы были размещены одна на другой.

Я прикрепил изображение к своему первому посту, которое показывает стиль таблицы, который мне нужен. Я снова загрузил стиль, который мне нужен, по следующему адресу: ufile.io/uppi0. Я хочу, чтобы этот стиль был на каждой странице, например, вторая страница начинается с номера 42 до 82 и так далее.

Sameer 29.05.2018 14:26

1) То есть под заголовком повторяющийся вы имеете в виду, что заголовок должен повторяться только на первой странице? 2) Предположим, что на странице можно разместить 20 строк. Какого результата вы ожидаете: а) или б)? а) 1 11 \ n 2 12 \ n ...... \ n 10 20 \ n ПЕРЕРЫВ 21 31 \ n 22 32 \ n ........ \ n 30 40 \ nb) 1 21 \ n 2 22 \ n ...... \ n 10 30 \ n ПЕРЕРЫВ 11 31 \ n 12 32 \ n ........ \ n 20 40 \ n

Uladzimir Asipchuk 29.05.2018 14:54

Я имею в виду, что на каждой странице у меня есть таблица с этими столбцами: номер, имя, семья, номер, имя, семья. Затем я хочу заполнить их точно так же, как рисунок, который я прикрепляю, и точную нумерацию, которая показана на рисунке, и заполнить таблицу этим шаблоном (как показано на рисунке), пока данные не будут завершены. Другими словами, я хочу иметь 41 запись на первой странице в стиле, показанном на рисунке, и 41 запись на второй странице и так далее.

Sameer 29.05.2018 20:27

Хорошо, тогда код, который я предоставил в ответе, вам поможет.

Uladzimir Asipchuk 30.05.2018 09:30

Нет, это не так, потому что он создал одну таблицу с 3 столбцами, а не с 6 столбцами, как я сказал, и пронумеровав каждую строку. Это совсем не соответствовало моему стилю.

Sameer 30.05.2018 23:10

Другие вопросы по теме