java - iText 无法将行保持在一起,第二行跨越多个页面,但不会与第一行保持一致

标签 java pdf pdf-generation itext

我无法使用 iText 将主 PdfPTable 的第一行和第二行放在一起。我的第一行包含一个包含一些基本信息的 PdfPTable。我的第二行包含一个 PdfPTable,其中包含所有列表信息。每当列表信息变得太大并跨越多个页面时,它就会自动跳到第二页,而不是直接显示在基本信息下方,然后分页到下一页。我怎样才能避免这个问题?我尝试过使用 setSplitRows(false),但我只是得到一个空白文档(请参阅注释行 117 和 170)。如何将表格数据(第二行)保留在第一页上?我的代码示例如下所示(您应该能够复制/粘贴)。

public class TestHelper{
    private TestEventHelper helper;

    public TestHelper(){
        super();
        helper  = new TestEventHelper();
    }



    public TestEventHelper getHelper() {
        return helper;
    }



    public void setHelper(TestEventHelper helper) {
        this.helper = helper;
    }



    public static void main(String[] args){
        TestHelper test = new TestHelper();
        TestEventHelper helper = test.getHelper();

        FileOutputStream file = null;
        Document document = null;
        PdfWriter writer = null;
        try {
            file = new FileOutputStream(new File("C://Documents and Settings//All Users//Desktop//pdffile2.pdf"));
            document = new Document(PageSize.A4.rotate(), 36, 36, 36, 36);

            writer = PdfWriter.getInstance(document, file);
//          writer.setPageEvent(templateHelper);
            writer.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
            writer.setUserunit(1f);
            document.open();

            List<Element> pages = null;
            try {
                pages = helper.createTemplate();
            } catch (Exception e) {
                e.printStackTrace();
            }

            Iterator<Element> iterator = pages.iterator();
            while (iterator.hasNext()) {
                Element element = iterator.next();
                if (element instanceof Phrase) {
                    document.newPage();
                } else {
                    document.add(element);
                }
            }

        } catch (Exception de) {
            de.printStackTrace();
//          log.debug("Exception " + de + " " + de.getMessage());
        } finally {
            if (document != null) {
                document.close();
            }
            if (writer != null) {
                writer.close();
            }
        }
        System.out.println("Done!");
    }


private class TestEventHelper extends PdfPageEventHelper{

    // The PdfTemplate that contains the total number of pages.
    protected PdfTemplate total;
    protected BaseFont helv;

    private static final float SMALL_MARGIN = 20f;
    private static final float MARGIN = 36f;
    private final Font font = new Font(Font.HELVETICA, 12, Font.BOLD);
    private final Font font2 = new Font(Font.HELVETICA, 10, Font.BOLD);
    private final Font smallFont = new Font(Font.HELVETICA, 10, Font.NORMAL);

    private String[] datatableHeaderFields = new String[]{"Header1", "Header2", "Header3", "Header4", "Header5", "Header6", "Header7", "Header8", "Header9"};
    public TestEventHelper(){
        super();
    }

    public List<Element> createTemplate() throws Exception {
        List<Element> elementList = new ArrayList<Element>();
        float[] tableWidths = new float[]{1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.25f, 1.25f, 1.25f, 1.25f};
//      logger.debug("entering create reports template...");

        PdfPTable splitTable = new PdfPTable(1);
        splitTable.setSplitRows(false);
        splitTable.setWidthPercentage(100f);

        PdfPTable pageTable = new PdfPTable(1);
        pageTable.setKeepTogether(true);
        pageTable.setWidthPercentage(100f);

        PdfPTable searchTable = generateSearchFields();
        if(searchTable != null){
            searchTable.setSpacingAfter(25f);
        }

        PdfPTable outlineTable = new PdfPTable(1);
        outlineTable.setKeepTogether(true);
        outlineTable.setWidthPercentage(100f);

        PdfPTable datatable = new PdfPTable(datatableHeaderFields.length);
        datatable.setKeepTogether(false);
        datatable.setWidths(tableWidths);


        generateDatatableHeader(datatable);

        for(int i = 0; i < 100; i++){
            addCell(datatable, String.valueOf(i), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
            addCell(datatable, String.valueOf(i+1), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
            addCell(datatable, String.valueOf(i+2), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
            addCell(datatable, String.valueOf(i+3), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
            addCell(datatable, String.valueOf(i+4), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
            addCell(datatable, String.valueOf(i+5), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
            addCell(datatable, String.valueOf(i+6), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
            addCell(datatable, String.valueOf(i+7), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
            addCell(datatable, String.valueOf(i+8), 1, Rectangle.NO_BORDER, Element.ALIGN_RIGHT, smallFont, true);
        }

        PdfPCell dataCell = new PdfPCell(datatable);
        dataCell.setBorder(Rectangle.BOX);
        outlineTable.addCell(dataCell);

        PdfPCell searchCell = new PdfPCell(searchTable);
        searchCell.setVerticalAlignment(Element.ALIGN_TOP);

        PdfPCell outlineCell = new PdfPCell(outlineTable);
        outlineCell.setVerticalAlignment(Element.ALIGN_TOP);

        addCell(pageTable, searchCell, 1, Rectangle.NO_BORDER, Element.ALIGN_LEFT, null, null);
        addCell(pageTable, outlineCell, 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, null, null);

        PdfPCell pageCell = new PdfPCell(pageTable);
        pageCell.setVerticalAlignment(Element.ALIGN_TOP);
        addCell(splitTable, pageCell, 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, null, null);

        elementList.add(pageTable);
//      elementList.add(splitTable);

        return elementList;
    }

    public void onOpenDocument(PdfWriter writer, Document document) {
        total = writer.getDirectContent().createTemplate(100, 100);
        total.setBoundingBox(new Rectangle(-20, -20, 100, 100));
        try {
            helv = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);
        } catch (Exception e) {
            throw new ExceptionConverter(e);
        }
    }

    public void onEndPage(PdfWriter writer, Document document) {
        //TODO
    }

    public void onCloseDocument(PdfWriter writer, Document document) {
        total.beginText();
        total.setFontAndSize(helv, 10);
        total.setTextMatrix(0, 0);
        total.showText(String.valueOf(writer.getPageNumber() - 1));
        total.endText();
    }

    private PdfPTable generateSearchFields(){
        PdfPTable searchTable = new PdfPTable(2);

        for(int i = 0; i < 6; i++){
            addCell(searchTable, "Search Key" +i, 1, Rectangle.NO_BORDER, Element.ALIGN_RIGHT, font2, MARGIN, true);
            addCell(searchTable, "Search Value +i", 1, Rectangle.NO_BORDER, Element.ALIGN_LEFT, smallFont, null, true);
        }
        return searchTable;
    }

    private void generateDatatableHeader(PdfPTable datatable) {
        if (datatableHeaderFields != null && datatableHeaderFields.length != 0) {
            for (int i = 0; i < datatableHeaderFields.length; i++) {
                addCell(datatable, datatableHeaderFields[i], 1, Rectangle.BOX, Element.ALIGN_CENTER, font2);
            }
        }
    }

    private PdfPCell addCell(PdfPTable table, String cellContent, int colspan, int cellBorder, int horizontalAlignment, Font font) {
        return addCell(table, cellContent, colspan, cellBorder, horizontalAlignment, font, null, null);
    }

    private PdfPCell addCell(PdfPTable table, String cellContent, int colspan, int cellBorder, int horizontalAlignment, Font font, Boolean noWrap) {
        return addCell(table, cellContent, colspan, cellBorder, horizontalAlignment, font, null, noWrap);
    }

    private PdfPCell addCell(PdfPTable table, String cellContent, Integer colspan, Integer cellBorder, Integer horizontalAlignment, Font font, Float paddingLeft, Boolean noWrap) {
        PdfPCell cell = new PdfPCell(new Phrase(cellContent, font));
        return addCell(table, cell, colspan, cellBorder, horizontalAlignment, paddingLeft, noWrap);
    }

    private PdfPCell addCell(PdfPTable table, PdfPCell cell, int colspan, int cellBorder, int horizontalAlignment, Float paddingLeft, Boolean noWrap) {
        cell.setColspan(colspan);
        cell.setBorder(cellBorder);
        cell.setHorizontalAlignment(horizontalAlignment);
        if(paddingLeft != null){
            cell.setPaddingLeft(paddingLeft);
        }
        if(noWrap != null){
            cell.setNoWrap(noWrap);
        }
        table.addCell(cell);
        return cell;
    }

}
}

最佳答案

该问题是由嵌套 PdfPTable 引起的。 iText 无法按照您想要的方式拆分包含大型表格的单个单元格。最好的选择是使用 2 个单独的表,第一个表用于顶部的基本信息,第二个表用于数据。

我通过注释掉 createTemplate() 中的一些嵌套代码来使您的代码正常工作

    public List<Element> createTemplate() throws Exception {
    List<Element> elementList = new ArrayList<Element>();
    float[] tableWidths = new float[]{1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.25f, 1.25f, 1.25f, 1.25f};
    //      logger.debug("entering create reports template...");

    PdfPTable splitTable = new PdfPTable(1);
    splitTable.setSplitRows(false);
    splitTable.setWidthPercentage(100f);

    PdfPTable pageTable = new PdfPTable(1);
    pageTable.setKeepTogether(true);
    pageTable.setWidthPercentage(100f);

    PdfPTable searchTable = generateSearchFields();
    if(searchTable != null){
        searchTable.setSpacingAfter(25f);
    }

    PdfPTable outlineTable = new PdfPTable(1);
    outlineTable.setKeepTogether(true);
    outlineTable.setWidthPercentage(100f);

    PdfPTable datatable = new PdfPTable(datatableHeaderFields.length);
    //        datatable.setKeepTogether(false);
    datatable.setWidths(tableWidths);


    generateDatatableHeader(datatable);

    for(int i = 0; i < 100; i++){
        addCell(datatable, String.valueOf(i), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
        addCell(datatable, String.valueOf(i+1), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
        addCell(datatable, String.valueOf(i+2), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
        addCell(datatable, String.valueOf(i+3), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
        addCell(datatable, String.valueOf(i+4), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
        addCell(datatable, String.valueOf(i+5), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
        addCell(datatable, String.valueOf(i+6), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
        addCell(datatable, String.valueOf(i+7), 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, smallFont, true);
        addCell(datatable, String.valueOf(i+8), 1, Rectangle.NO_BORDER, Element.ALIGN_RIGHT, smallFont, true);
    }

    //        PdfPCell dataCell = new PdfPCell(datatable);
    //        dataCell.setBorder(Rectangle.BOX);
    //        outlineTable.addCell(dataCell);
    //
    //        PdfPCell searchCell = new PdfPCell(searchTable);
    //        searchCell.setVerticalAlignment(Element.ALIGN_TOP);
    //
    //        PdfPCell outlineCell = new PdfPCell(outlineTable);
    //        outlineCell.setVerticalAlignment(Element.ALIGN_TOP);
    //
    //        addCell(pageTable, searchCell, 1, Rectangle.NO_BORDER, Element.ALIGN_LEFT, null, null);
    //        addCell(pageTable, outlineCell, 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, null, null);
    //
    //        PdfPCell pageCell = new PdfPCell(pageTable);
    //        pageCell.setVerticalAlignment(Element.ALIGN_TOP);
    //        addCell(splitTable, pageCell, 1, Rectangle.NO_BORDER, Element.ALIGN_CENTER, null, null);

    elementList.add(searchTable);
    elementList.add(datatable);
    //      elementList.add(pageTable);
    //      elementList.add(splitTable);

    return elementList;
}

关于java - iText 无法将行保持在一起,第二行跨越多个页面,但不会与第一行保持一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2959193/

相关文章:

java - Spring Boot Cache + Apache ignite + Spring Boot Actuator - 运行测试时应用程序无法启动

java - 在Java中从JTable创建pdf文件

c# - 按目录中的章节拆分 PDF

python - Tabula 按区域坐标提取表格

python - 在 Python 中使用 ReportLabs 生成报告

pdf-generation - FullCalendar 可以打印为 PDF 吗?

java - FlatMapFunction 没有定义serialversionUid

java - 如何获取任何 JPA 实体的主键?

c# - 如何使用 itextsharp 将页码添加到每个 pdf 页面

java - 从HashMap中获取包含字符串片段的key