当前位置: 首页 > 知识库问答 >
问题:

从PdfPTable列获取绝对宽度(iText)

长孙朝明
2023-03-14
PdfPCell cell2;
PdfPTable table2 =  new PdfPTable(new float[]{(float) 4.5, (float) 0.5, 9});
table2.setWidthPercentage(100);

我尝试使用Table2.GetAbsoluteWidths()[2],但结果是float0.0

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

----------------编辑----------------------------------

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个答案

姜德容
2023-03-14

函数table.GetAbsoluteWidths()依赖于必须设置表的totalWidth的要求,因此table.GetTotalWidth()>0

这是因为在com.itextpdf.text.pdf.pdfptable类内部调用了一个方法CalculateWidths(),然后该方法计算所有列的绝对宽度:

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

为了确保在检索relativeWidths数组之前设置了totalWidth,您需要:

  • 或者(A)设置totalWidth(如本答案所述)
  • 或(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。我了解到,每一列的每个单元格/列的宽度都相同(默认值),或者可以设置每一列应占用的空间比例。 但是,我希望列的宽度可以根据需要而定,但不要任何宽度都取决于插入的数据。假设表格很容易放在页面上(不间断!)。当然,我可以手动浏览所有数据并计算每列的最大字符串长度,并相应地设置表的属性,但是我想知道itext本身是否已经提供了这样一个通

  • 问题内容: 我知道什么是绝对位置和相对位置,但是我仍然不清楚一些要点。以供参考 CSS: 的HTML: 现在的要点是: 相对div自动采用100%宽度,但绝对div仅采用内容宽度。为什么? 当我给高度100%时,相对div无效,但绝对div的高度为100%。为什么? 当我给margin-top:30px时,它也偏移绝对div,但是当我给top:30px时,则只有相对div偏移。为什么? 当我不给绝

  • 问题内容: 因此,警报会给出宽度和高度的不确定值。我认为img.onload计算中图像的w和h值未传递给要返回的值,或者可能在onload计算它们 之前 返回了w和h : 如何让警报显示正确的宽度和高度? 问题答案: 使用jQuery获取图像大小 使用JavaScript获取图像大小 使用JavaScript获取图像大小 (现代浏览器,IE9 +) 只需将以上内容用作:

  • 问题内容: 我一直在寻找一种从C程序中获取终端宽度的方法。我不断提出的思路是: 但是每次我尝试得到 这是执行此操作的最佳方法,还是有更好的方法?如果没有,我该如何工作? 编辑:固定代码是 问题答案: 您是否考虑过使用getenv()?它使您可以获取包含端子列和行的系统环境变量。 或者,使用您的方法,如果您想查看内核显示的终端大小(最好是在调整终端大小时),则需要使用TIOCGWINSZ而不是TIO

  • 我有一个base64 img编码,你可以在这里找到。我怎样才能得到它的高度和宽度?

  • 好了,我理解了调整窗格中对象大小的绑定原则,这个问题有点不同。我很困惑,我试图创建一个扩展Pane的类,在我的main中创建一条线,将它的startX和startY坐标绑定到窗格的中心。问题是,当使用getWidth() / 2或getHeight() /2时,当我按下箭头键时,坐标被放置在起始坐标(0,0)的左上某处,当按下箭头键时,它会创建另一条线,该线在按下的给定方向上绘制,并从最后一条线的