iText不能将行放在一起,第二行跨越多个页面,但不会坚持第一行

时间:2022-05-23 21:10:11

I am having trouble keeping my first and second rows of my main PdfPTable together using iText. My first row consists of a PdfPTable with some basic information. My second row consists of a PdfPTable that contains all of the tabulated info. Every time the tabulated info becomes too big and spans multiple pages, it is kicked to the second page automatically rather than showing up directly below the basic info and then paging to the next page. How can I avoid this problem? I have tried using setSplitRows(false), but I simply get a blank document (see commented lines 117 and 170). How can I keep my tabulated data (second row) up on the first page? An example of my code is shown below (you should be able to just copy/paste).

我无法使用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;
    }

}
}

1 个解决方案

#1


2  

The problem is caused by having nested PdfPTables. iText cannot split a single cell containing a large table in the way you want. The best option is to use 2 separate tables, 1 for your basic information at the top, and a second one for the data.

问题是由嵌套的PdfPTables造成的。iText不能以您希望的方式分割包含大型表的单个单元格。最好的选择是使用两个单独的表,一个用于最上面的基本信息,另一个用于数据。

I got your code to work by commenting out some the nesting code in createTemplate()

我通过在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;
}

#1


2  

The problem is caused by having nested PdfPTables. iText cannot split a single cell containing a large table in the way you want. The best option is to use 2 separate tables, 1 for your basic information at the top, and a second one for the data.

问题是由嵌套的PdfPTables造成的。iText不能以您希望的方式分割包含大型表的单个单元格。最好的选择是使用两个单独的表,一个用于最上面的基本信息,另一个用于数据。

I got your code to work by commenting out some the nesting code in createTemplate()

我通过在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;
}