Получить абсолютную ширину из столбца PdfPTable (iText)
Как получить абсолютную ширину столбца из iText, когда столбцы таблицы указаны с их относительным размером?
Что я пробовал
Я указал 3 столбца с их относительной шириной как float:
PdfPCell cell2;
PdfPTable table2 = new PdfPTable(new float[]{(float) 4.5, (float) 0.5, 9});
table2.setWidthPercentage(100);
Что я имею
Я пытался использовать table2.getAbsoluteWidths()[2]
но результат плавать 0.0
,
Что я ожидал
Я хочу получить абсолютную ширину (которая была максимизирована) для каждого столбца после динамического расчета ширины таблицы в PDF.
----------------------- РЕДАКТИРОВАТЬ ----------------------
На самом деле мне нужно ширину столбца, прежде чем документ добавлен, а затем заменить ограничение жесткого плавающего кода.
У меня есть много строк данных и хочу установить в другом столбце, когда получить максимальную ширину страницы с разделением в функции restrictWidthOfFont
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;
}
что можно получить ширину столбца до добавления документа таблицы?
1 ответ
Проблема и объяснение
Функция table.getAbsoluteWidths()
полагается на требование, что общая ширина таблицы должна быть установлена, следовательно, table.getTotalWidth() > 0
,
Это потому, что внутри com.itextpdf.text.pdf.PdfPTable
класс метод calculateWidths()
вызывается, который затем вычисляет абсолютную ширину всех столбцов:
this.absoluteWidths[k] = this.totalWidth * this.relativeWidths[k] / total;
Решение
Чтобы удостовериться, что totalWidth установлен перед извлечением массива lativeWidths, вам необходимо:
- либо (A) установите общую ширину, как описано в этом ответе
- или (B) добавить ячейки в таблицу и добавить таблицу в документ
Код для решения
Следующий код включает в себя ваш алгоритм для разделения текста (например, длинный адрес или alamat) по ячейкам на основе ограничения максимальной ширины столбца:
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 динамически вычислять ширину столбца