Получить абсолютную ширину из столбца PdfPTable (iText)

Как получить абсолютная ширина столбца из iText, когда столбцы таблицы указаны с их относительный размер?

Что я пробовал

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

PdfPCell cell2;
PdfPTable table2 =  new PdfPTable(new float[]{(float) 4.5, (float) 0.5, 9});
table2.setWidthPercentage(100);

Что я имею

Я пытался использовать table2.getAbsoluteWidths()[2], но результат плавает 0.0.

Что я ожидал

Я хочу получить абсолютная ширина (который был максимальным) для каждого столбца после динамического расчета ширины таблицы в PDF.

----------------------- РЕДАКТИРОВАТЬ ----------------------

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

У меня много строк данных и я хочу установить в другом столбце, когда получаю страницу максимальной ширины с разделением в функции ограничитьWidthOfFont

String fullAlamatPP = "test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test ";

float restrictions = (float) 330.12103; // this is width of a column from table

String alamatSesuaiKtpPP[] = restrictWidthOfFont(fullAlamatPP, font_body, restrictions);

Phrase p_alamat1_ct = new Phrase(alamatSesuaiKtpPP[0], font_body);
p_alamat1_ct.add(dottedline);
cell2 = new PdfPCell(p_alamat1_ct);
cell2.setBorder(PdfPCell.NO_BORDER);
table2.addCell(cell2);

Phrase p_alamat2_ct = new Phrase(alamatSesuaiKtpPP[1], font_body);
p_alamat2_ct.add(dottedline);
cell2 = new PdfPCell(p_alamat2_ct);
cell2.setBorder(PdfPCell.NO_BORDER);
table2.addCell(cell2);    

private static String[] restrictWidthOfFont(String character, Font font, float restrictions) {
        String results[];
        results = new String[] {"",""};
        String concatChar = " ";
        float widthOfString = 0;
        for (int i = 0; i < character.length();i++) {
            concatChar += character.charAt(i); 
            widthOfString = font.getCalculatedBaseFont(true).getWidthPoint(concatChar, font.getCalculatedSize());
//                System.out.println("widthOfString " + widthOfString);
            if (widthOfString > restrictions) {
                results[0] = concatChar.substring(0, concatChar.length() - 1);
                results[1] = character.substring(i, character.length());
                break;
            }
        }

        if (results[0] == "") {
            results[0] = character;
        }
        return results;
}    

можно ли получить ширину столбца перед добавлением табличного документа?

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

Ответы 1

Ответ принят как подходящий

Проблема и объяснение

Функция table.getAbsoluteWidths() основана на требовании, что общая ширина таблицы должен быть установлен, следовательно, table.getTotalWidth() > 0.

Это связано с тем, что внутри класса com.itextpdf.text.pdf.PdfPTable вызывается метод calculateWidths(), который затем вычисляет абсолютную ширину всех столбцов:

this.absoluteWidths[k] = this.totalWidth * this.relativeWidths[k] / total;

Решение

Чтобы убедиться, что общая ширина равен установить перед, вы получаете массив относительная ширина, вам необходимо:

  • либо (А) установить общая ширина, как описано в этот ответ
  • или (B) добавить ячейки в таблицу и добавить таблицу в документ

Код для решения

Следующий код включает ваш алгоритм для разделить текст (т. е. длинный адрес или аламат) по ячейкам на основе ограничения максимальная ширина столбца:

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class TableWidthSample {

    public static void main(String[] args) {
        Document document = new Document();
        try {
            PdfWriter.getInstance(document, new FileOutputStream("TableColumnWidth.pdf"));
            document.open();

            PdfPTable table = createTableWithRelativeColumnWidths();

            // needed for calculation of getAbsoluteWidths: (A) totalWidth is set for table
            table.setTotalWidth(calculateTableWidthBasedOnPageA4(document, table));
            // now it prints width, because (A)
            printTableWidth(table, "after totalWidth set manually"); // absoluteWidths: [134.4857, 14.942857, 268.9714]

            // long text, that needs to be split among cells (fullAlamatPP)
            String text = "this is a very long text. The text contains a full address. Because the text is too long to be shown in the last cell, it is split.";
            // your CODE to fill text into cells based on restrictions
            addTextAcrossTableCells(table, text);

            document.add(table);

/*
            // need to add filled table to doc (B)
            addToDocumentCellsAndTable(document, table);
            // now it prints width, because (B)
            printTableWidth(table, "after added to doc"); // absoluteWidths: [134.4857, 14.942857, 268.9714]
*/
            document.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static PdfPTable createTableWithRelativeColumnWidths() {
        float[] relativeWidths = {4.5F, 0.5F, 9F};
        PdfPTable table = new PdfPTable(relativeWidths);
        table.setWidthPercentage(100F);
        printTableWidth(table, "after table created"); // absoluteWidths: [0.0, 0.0, 0.0]
        return table;
    }

    private static float calculateTableWidthBasedOnPageA4(Document document, PdfPTable table) {
        return (PageSize.A4.getWidth() - document.leftMargin() - document.rightMargin())
                * table.getWidthPercentage() / 100;
    }

    private static void addToDocumentCellsAndTable(Document document, PdfPTable table) throws DocumentException {
        // needed for calculation of getAbsoluteWidths: (B.1) add cells to table
        table.addCell("Hello");
        table.addCell("World");
        table.addCell("!");
        printTableWidth(table, "after cells added to table"); // absoluteWidths: [0.0, 0.0, 0.0]

        // needed for calculation of getAbsoluteWidths: (B.2) add table to doc
        document.add(table);
    }

    private static void addTextAcrossTableCells(PdfPTable table, String text) throws IOException, DocumentException {
        // restrictions; this is width of a column from table
        float maxColumnWidth = table.getAbsoluteWidths()[2]; // 330.12103F;
        System.out.println("use width of third column as max: " + maxColumnWidth);
        // sample font used for calculation of text-width
        Font font = new Font(BaseFont.createFont("Courier", BaseFont.CP1250, true), 12);

        // alamatSesuaiKtpPP
        String splitText[] = getTextPartsUsingFontWithMaxWidth(text, font, maxColumnWidth);
        String dottedLine = "..";
        table.addCell("Alamat / Address:");

        // p_alamat1_ct
        Phrase phrase1 = new Phrase(splitText[0], font);
        phrase1.add(dottedLine);
        PdfPCell cell1 = new PdfPCell(phrase1);
        cell1.setBackgroundColor(BaseColor.LIGHT_GRAY);
        cell1.setBorder(PdfPCell.NO_BORDER);
        table.addCell(cell1);

        // p_alamat2_ct
        Phrase phrase2 = new Phrase(splitText[1], font);
        phrase2.add(dottedLine);
        PdfPCell cell2 = new PdfPCell(phrase2);
        cell2.setBorder(PdfPCell.NO_BORDER);
        table.addCell(cell2);
    }

    private static String[] getTextPartsUsingFontWithMaxWidth(String text, Font font, float maxWidth) {
        String results[] = new String[] {"",""};
        String firstPartOfText = " ";
        float widthOfText = 0;
        for (int i = 0; i < text.length();i++) {
            firstPartOfText += text.charAt(i);
            widthOfText = font.getCalculatedBaseFont(true).getWidthPoint(firstPartOfText, font.getCalculatedSize());
            System.out.printf("%d: widthOfText: %f\n", i, widthOfText);
            if (widthOfText > maxWidth) {
                results[0] = firstPartOfText.substring(0, firstPartOfText.length() - 1);
                results[1] = text.substring(i); // second argument "text.length()" is not needed
                break;
            }
        }

        if (results[0] == "") {
            results[0] = text;
        }
        return results;
    }

    private static void printTableWidth(PdfPTable table, String labelText) {
        float[] absoluteWidths = table.getAbsoluteWidths();
        System.out.println(labelText + "> getAbsoluteWidths: " + Arrays.toString(absoluteWidths));
    }
}

Смотрите также

Как заставить PdfPTable динамически рассчитывать ширину столбца

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