java - 如何将可滚动的 JPanel 导出为 pdf 文件

标签 java swing pdf jpanel itext

我设计了一个 jpanel,其中包含许多具有可滚动功能的 Swing 组件。我想将整个 Jpanle 导出到 pdf 文件中。但我无法导出整个 Jpanle。 我使用 itext 生成 pdf。 我的问题是我无法将整个 jpanel 导出为 pdf。当我导出一半的Jpanel时 组件导出。但一半不导出。 这是我的代码。

public void PrintFrameToPDF(JPanel c, File file) {
    try {           
        Document d = new Document();
        PdfWriter writer = PdfWriter.getInstance(d, new FileOutputStream("F://newfile.pdf"));
        d.open();

        PdfContentByte cb = writer.getDirectContent();
        PdfTemplate template = cb.createTemplate(800, 1600);
        Graphics2D g2d = template.createGraphics(800, 1600);
        // g2d.translate(1.0, 1.0);
        c.paintAll(g2d);
        // c.addNotify();
        // c.validate();
        g2d.dispose();
        cb.addTemplate(template, 0, 0);
        d.close();          
    } catch (Exception e) {
        //
    }
}

请帮助我。 tnx

最佳答案

考虑创建一个 java.awt.Image首先从面板(通过将面板绘制到图像)。然后您可以获得 com.itextpdf.text.Image 的实例使用:

com.itextpdf.text.Image.getInstance(PdfWriter writer, java.awt.Image awtImage, float quality) -
Gets an instance of a com.itextpdf.textImage from a java.awt.Image. The image is added as a JPEG with a user defined quality.

然后您可以使用 com.itextpdf.text.Image API 缩放图像方法scaleToFitscalePercent() (如下例中所使用)。有关使用图像(在 iText 中)的更多信息,请参阅 here

以下程序创建一个大小为 2000x2000 的面板,其中将 20x20 的正方形(每个 100 像素)绘制到面板上。该面板包含在滚动 Pane 内。然后将其绘制到图像上,图像将被缩放并添加到 pdf 文档并打印为 pdf。

下图仅显示了如何将整个面板绘制到图像上,然后使用前一个面板图像创建另一个面板,以绘制到新面板上。然后通过对话框显示新面板。

enter image description here

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * This example requires iText. I retrieved it from Maven repository
 * 
 *      <dependency>
 *          <groupId>com.itextpdf</groupId>
 *          <artifactId>itextpdf</artifactId>
 *          <version>5.5.2</version>
 *      </dependency>
 *
 * The program can be run without iText if you comment out the entire
 * method printToPDF (and iText imports), along with it's method call in 
 * the class constructor. The result will be the the image above.
 */

public class LargePanelToImageMCVE {

    public LargePanelToImageMCVE() {
        LargeImagePanel panel = new LargeImagePanel();
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(panel));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setVisible(true);

        final java.awt.Image image = getImageFromPanel(panel);

        /* This was just a text panel to make sure the full panel was
         * drawn to the panel.
         */
        JPanel newPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 300);
            }
        };

        /* Print Image to PDF */
        String fileName = "D://newfile.pdf";
        printToPDF(image, fileName);

        /* This was just a test to show the newPanel drew the entire
         * original panel (scaled)
         */
        JOptionPane.showMessageDialog(null, newPanel);

    }

    public void printToPDF(java.awt.Image awtImage, String fileName) {
        try {
            Document d = new Document();
            PdfWriter writer = PdfWriter.getInstance(d, new FileOutputStream(
                    fileName));
            d.open();


            Image iTextImage = Image.getInstance(writer, awtImage, 1);
            iTextImage.setAbsolutePosition(50, 50);
            iTextImage.scalePercent(25);
            d.add(iTextImage);

            d.close();

        } catch (Exception e) {
            e.printStackTrace();
        }   
    }

    public static java.awt.Image getImageFromPanel(Component component) {

        BufferedImage image = new BufferedImage(component.getWidth(),
                component.getHeight(), BufferedImage.TYPE_INT_RGB);
        component.paint(image.getGraphics());
        return image;
    }

    /**
     * Demo panel that is 2000x2000 px with alternating squares
     * to check all squares are drawn to image
     */
    public class LargeImagePanel extends JPanel {
        private static final int FULL_SIZE = 2000;
        private static final int PER_ROW_COLUMN = 20;
        private static final int SQUARE_SIZE = FULL_SIZE / PER_ROW_COLUMN;

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            for (int row = 0; row < PER_ROW_COLUMN; row++) {
                for (int col = 0; col < PER_ROW_COLUMN; col++) {
                    if ((row % 2) == (col % 2)) {
                        g.setColor(Color.BLACK);
                    } else {
                        g.setColor(Color.WHITE);
                    }
                    g.fillRect(col * SQUARE_SIZE, row * SQUARE_SIZE,
                            SQUARE_SIZE, SQUARE_SIZE);
                }
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(FULL_SIZE, FULL_SIZE);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new LargePanelToImageMCVE();
            }
        });
    }
}

关于java - 如何将可滚动的 JPanel 导出为 pdf 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25579480/

相关文章:

java - 如何实现@RequestMapping 自定义属性

Java - 在包含 HTML 的 JTextPane 中更改字体

r - 在特定时间从 R 自动通过电子邮件发送 pdf 图形输出

php - DomPDF 的 get_cellmap() 问题

java - 强制 JAXB 将空元素解释为 Null 而不是空字符串

java - Bootstrap 选项卡在 Java/Spring Boot 应用程序中无法正常工作

java - 当我使用继承实体的存储库时如何修复 "No property [repositoryMethod] found for type [entity]!"?

Java框架图标化问题

java - 删除 JComboBox 内的文件

ios - 使用 Swift 在 UIWebView 中旋转 PDF