iText swing component to more then one page

2019-03-04 18:05发布

问题:

I have a jpanel that will have a pretty big height that i want to paint into a pdf,something like 2-3 pages,sometimes even more. My issue is that it will not pass on to the next page,it will just try and insert everything into the first page and when the page ends it won't pass to the next one. I searched a bit,tried everything i could figure out,nothing. How can i do that,how can i tell iText that it needs to start a new page and continue with the jpanel there ? Here's my code:

try {
        Document document = new Document(PageSize.A4);

        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:\\HelloWorld.pdf"));
        document.open();
        jPanel1.addNotify();
        jPanel1.validate();         
        PdfContentByte cb = writer.getDirectContent();
        PdfTemplate tp = cb.createTemplate(600, 840);
        Graphics2D g2d = tp.createGraphics(595, 840);
        g2d.translate(4, 4);
        g2d.scale(0.708, 0.8);
        jPanel1.paint(g2d);
        cb.addTemplate(tp, 0, 0);
        g2d.dispose();
        document.close();
    } catch (DocumentException ex) {

    } catch (FileNotFoundException ex) {
    }

回答1:

You use the JPanel only to create the graphics (to paint on g2d), it has nothing to do with your problem per se.

As images don't have "natural" wrap boundaries (like words or paragraphs) you need to do this yourself. Split the image, i.e. create several images manual at useful boundaries (depending on the content, probably you need to adapt the paint method) and place them on separate pages.



回答2:

You can create a big enough template and draw all the JPanel content to that template. Then you add this single template to different pdf pages using different offsets and, consequently, display different sections of the template on the individual pages.

E.g. in case of a sample panel (3 pages high)

class MyPanel extends JPanel {

    public MyPanel(Rectangle baseSize) {
        setBorder(BorderFactory.createLineBorder(Color.black));
        this.baseSize = baseSize;
    }

    public Dimension getPreferredSize() {
        return new Dimension((int)baseSize.getWidth(), ((int)baseSize.getHeight()) * 3);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);       

        g.drawString("Page 1", 10, 20);
        g.drawRoundRect(5, 5, (int)baseSize.getWidth() - 10, (int)baseSize.getHeight() - 10, 15, 15);
        g.drawString("Page 2", 10, 20 + (int)baseSize.getHeight());
        g.drawRoundRect(5, 5 + (int)baseSize.getHeight(), (int)baseSize.getWidth() - 10, (int)baseSize.getHeight() - 10, 15, 15);
        g.drawString("Page 3", 10, 20 + 2 * (int)baseSize.getHeight());
        g.drawRoundRect(5, 5 + 2 * (int)baseSize.getHeight(), (int)baseSize.getWidth() - 10, (int)baseSize.getHeight() - 10, 15, 15);
    }

    final Rectangle baseSize;
}

you can spread the information on multiple PDF pges like this:

public void test() throws FileNotFoundException, DocumentException
{
    MyPanel panel = new MyPanel(PageSize.A4);
    panel.setSize(panel.getPreferredSize());

    Document document = new Document(PageSize.A4);

    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("target/test-outputs/big-panel.pdf"));
    document.open();
    panel.addNotify();
    panel.validate();         
    PdfContentByte cb = writer.getDirectContent();
    PdfTemplate tp = cb.createTemplate(panel.getWidth(), panel.getHeight());
    Graphics2D g2d = new PdfGraphics2D(tp, panel.getWidth(), panel.getHeight());
    panel.paint(g2d);
    g2d.dispose();
    cb.addTemplate(tp, 0, -2 * PageSize.A4.getHeight());
    document.newPage();
    cb.addTemplate(tp, 0, -PageSize.A4.getHeight());
    document.newPage();
    cb.addTemplate(tp, 0, 0);
    document.newPage();
    cb.addTemplate(tp, 0.3333f, 0, 0, 0.3333f, PageSize.A4.getWidth() / 3, 0);
    document.close();
}

As you see parts of the panel can be shown as individual pages; or the whole panel can be shown on one page scaled down. Of course you could also show small sections of the panel scaled up. Or rotated. Or ...