猿问

从 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]但结果是 float 0.0。


我所期望的

在 PDF 上动态计算表格宽度之后,我想获得每一列的绝对宽度(最大化)。



一只斗牛犬
浏览 464回答 1
1回答

三国纷争

问题及说明该函数table.getAbsoluteWidths()依赖于必须设置表的totalWidthtable.getTotalWidth() > 0的要求,因此.这是因为在com.itextpdf.text.pdf.PdfPTable类内部调用了一个方法calculateWidths(),然后计算所有列的绝对宽度:this.absoluteWidths[k]&nbsp;=&nbsp;this.totalWidth&nbsp;*&nbsp;this.relativeWidths[k]&nbsp;/&nbsp;total;解决方案为了确保在检索relativeWidths数组之前设置了totalWidth,您需要:(A)设置totalWidth&nbsp;,如this answer中所述或(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 {&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; Document document = new Document();&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PdfWriter.getInstance(document, new FileOutputStream("TableColumnWidth.pdf"));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; document.open();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PdfPTable table = createTableWithRelativeColumnWidths();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // needed for calculation of getAbsoluteWidths: (A) totalWidth is set for table&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table.setTotalWidth(calculateTableWidthBasedOnPageA4(document, table));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // now it prints width, because (A)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printTableWidth(table, "after totalWidth set manually"); // absoluteWidths: [134.4857, 14.942857, 268.9714]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // long text, that needs to be split among cells (fullAlamatPP)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 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.";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // your CODE to fill text into cells based on restrictions&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addTextAcrossTableCells(table, text);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; document.add(table);/*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // need to add filled table to doc (B)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addToDocumentCellsAndTable(document, table);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // now it prints width, because (B)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printTableWidth(table, "after added to doc"); // absoluteWidths: [134.4857, 14.942857, 268.9714]*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; document.close();&nbsp; &nbsp; &nbsp; &nbsp; } catch (FileNotFoundException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; } catch (DocumentException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; } catch (IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private static PdfPTable createTableWithRelativeColumnWidths() {&nbsp; &nbsp; &nbsp; &nbsp; float[] relativeWidths = {4.5F, 0.5F, 9F};&nbsp; &nbsp; &nbsp; &nbsp; PdfPTable table = new PdfPTable(relativeWidths);&nbsp; &nbsp; &nbsp; &nbsp; table.setWidthPercentage(100F);&nbsp; &nbsp; &nbsp; &nbsp; printTableWidth(table, "after table created"); // absoluteWidths: [0.0, 0.0, 0.0]&nbsp; &nbsp; &nbsp; &nbsp; return table;&nbsp; &nbsp; }&nbsp; &nbsp; private static float calculateTableWidthBasedOnPageA4(Document document, PdfPTable table) {&nbsp; &nbsp; &nbsp; &nbsp; return (PageSize.A4.getWidth() - document.leftMargin() - document.rightMargin())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; * table.getWidthPercentage() / 100;&nbsp; &nbsp; }&nbsp; &nbsp; private static void addToDocumentCellsAndTable(Document document, PdfPTable table) throws DocumentException {&nbsp; &nbsp; &nbsp; &nbsp; // needed for calculation of getAbsoluteWidths: (B.1) add cells to table&nbsp; &nbsp; &nbsp; &nbsp; table.addCell("Hello");&nbsp; &nbsp; &nbsp; &nbsp; table.addCell("World");&nbsp; &nbsp; &nbsp; &nbsp; table.addCell("!");&nbsp; &nbsp; &nbsp; &nbsp; printTableWidth(table, "after cells added to table"); // absoluteWidths: [0.0, 0.0, 0.0]&nbsp; &nbsp; &nbsp; &nbsp; // needed for calculation of getAbsoluteWidths: (B.2) add table to doc&nbsp; &nbsp; &nbsp; &nbsp; document.add(table);&nbsp; &nbsp; }&nbsp; &nbsp; private static void addTextAcrossTableCells(PdfPTable table, String text) throws IOException, DocumentException {&nbsp; &nbsp; &nbsp; &nbsp; // restrictions; this is width of a column from table&nbsp; &nbsp; &nbsp; &nbsp; float maxColumnWidth = table.getAbsoluteWidths()[2]; // 330.12103F;&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("use width of third column as max: " + maxColumnWidth);&nbsp; &nbsp; &nbsp; &nbsp; // sample font used for calculation of text-width&nbsp; &nbsp; &nbsp; &nbsp; Font font = new Font(BaseFont.createFont("Courier", BaseFont.CP1250, true), 12);&nbsp; &nbsp; &nbsp; &nbsp; // alamatSesuaiKtpPP&nbsp; &nbsp; &nbsp; &nbsp; String splitText[] = getTextPartsUsingFontWithMaxWidth(text, font, maxColumnWidth);&nbsp; &nbsp; &nbsp; &nbsp; String dottedLine = "..";&nbsp; &nbsp; &nbsp; &nbsp; table.addCell("Alamat / Address:");&nbsp; &nbsp; &nbsp; &nbsp; // p_alamat1_ct&nbsp; &nbsp; &nbsp; &nbsp; Phrase phrase1 = new Phrase(splitText[0], font);&nbsp; &nbsp; &nbsp; &nbsp; phrase1.add(dottedLine);&nbsp; &nbsp; &nbsp; &nbsp; PdfPCell cell1 = new PdfPCell(phrase1);&nbsp; &nbsp; &nbsp; &nbsp; cell1.setBackgroundColor(BaseColor.LIGHT_GRAY);&nbsp; &nbsp; &nbsp; &nbsp; cell1.setBorder(PdfPCell.NO_BORDER);&nbsp; &nbsp; &nbsp; &nbsp; table.addCell(cell1);&nbsp; &nbsp; &nbsp; &nbsp; // p_alamat2_ct&nbsp; &nbsp; &nbsp; &nbsp; Phrase phrase2 = new Phrase(splitText[1], font);&nbsp; &nbsp; &nbsp; &nbsp; phrase2.add(dottedLine);&nbsp; &nbsp; &nbsp; &nbsp; PdfPCell cell2 = new PdfPCell(phrase2);&nbsp; &nbsp; &nbsp; &nbsp; cell2.setBorder(PdfPCell.NO_BORDER);&nbsp; &nbsp; &nbsp; &nbsp; table.addCell(cell2);&nbsp; &nbsp; }&nbsp; &nbsp; private static String[] getTextPartsUsingFontWithMaxWidth(String text, Font font, float maxWidth) {&nbsp; &nbsp; &nbsp; &nbsp; String results[] = new String[] {"",""};&nbsp; &nbsp; &nbsp; &nbsp; String firstPartOfText = " ";&nbsp; &nbsp; &nbsp; &nbsp; float widthOfText = 0;&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < text.length();i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; firstPartOfText += text.charAt(i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; widthOfText = font.getCalculatedBaseFont(true).getWidthPoint(firstPartOfText, font.getCalculatedSize());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("%d: widthOfText: %f\n", i, widthOfText);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (widthOfText > maxWidth) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; results[0] = firstPartOfText.substring(0, firstPartOfText.length() - 1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; results[1] = text.substring(i); // second argument "text.length()" is not needed&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (results[0] == "") {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; results[0] = text;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return results;&nbsp; &nbsp; }&nbsp; &nbsp; private static void printTableWidth(PdfPTable table, String labelText) {&nbsp; &nbsp; &nbsp; &nbsp; float[] absoluteWidths = table.getAbsoluteWidths();&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(labelText + "> getAbsoluteWidths: " + Arrays.toString(absoluteWidths));&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Java
我要回答