如何将JEditorPane保存为pdf?

时间:2017-01-10 19:02:55

标签: java swing pdf

单击保存按钮后,我正在尝试将JEditorPane中的文本另存为pdf。

saveAs.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {

            String title = JOptionPane.showInputDialog(null, "Enter a name for file...");
            try{
                paintToPDF(newBlanktoEdit, title);
            }catch (Exception exc){
                exc.printStackTrace();
            }
        }
    });

方法paintToPDF正确完成工作,但Pane被解析为graphics2D组件,因此无法包装该行。

protected void paintToPDF(JEditorPane newPane, String title) throws Exception{

    newPane.setBounds(0, 0, (int) convertToPixels(612 - 58), (int) convertToPixels(792 - 60));

    Document doc = new Document();
    FileOutputStream out = new FileOutputStream(title + ".pdf");
    PdfWriter writer = PdfWriter.getInstance(doc, out);

    doc.setPageSize(new com.lowagie.text.Rectangle(612, 792));
    doc.open();
    PdfContentByte cb = writer.getDirectContent();
    cb.saveState();
    cb.concatCTM(1, 0, 0, 1, 0, 0);

    DefaultFontMapper mapper = new DefaultFontMapper();
    mapper.insertDirectory("c:/windows/fonts");

    Graphics2D g = cb.createGraphics(612, 792, mapper, true, .92f);

    AffineTransform at = new AffineTransform();
    at.translate(convertToPixels(20), convertToPixels(20));
    at.scale(pixelToPoint, pixelToPoint);

    g.transform(at);
    g.setColor(Color.WHITE);
    g.fill(newPane.getBounds());

    Rectangle alloc = getVisivleEditorRect(newPane);
    newPane.getUI().getRootView(newPane).paint(g, alloc);

    g.setColor(Color.BLACK);
    g.draw(newPane.getBounds());

    g.dispose();
    cb.restoreState();
    doc.close();
    out.flush();
    out.close();
}

private float convertToPixels(int points){

    return (float) (points / pixelToPoint);
}

private Rectangle getVisivleEditorRect(JEditorPane newPane){

    Rectangle alloc = newPane.getBounds();
    if((alloc.width > 0) && (alloc.height > 0)){
        alloc.x = alloc.y = 0;
        Insets insets = newPane.getInsets();
        alloc.x += insets.left;
        alloc.y += insets.top;
        alloc.width -= insets.left + insets.right;
        alloc.height -= insets.top + insets.bottom;
        return alloc;
    }
    return null;
}

with,

int inch = Toolkit.getDefaultToolkit().getScreenResolution();
float pixelToPoint = (float) 72 / (float) inch;

我正在寻找基于外部库的解决方案,我尝试使用iText和PDFBox进行实验,到目前为止无济于事。

我想指出上面的解决方案使用com.lowagie库。

1 个答案:

答案 0 :(得分:1)

根据我的理解,您希望将GUI转换为图像并以PDF格式打印,如果这不是您想要的,请澄清。

这是一个简单的程序,它创建了以下GUI(没有写入文本),这是JTextAreaJButton

enter image description here

单击时,该按钮将打开一个新文档,获取该区域并将其转换为图像,然后将该图像添加到PDF中,稍后对该按钮执行相同操作,因此您可以在PDF中获得类似的输出之一:

enter image description here

诀窍是使用java.awt.Imagecom.itextpdf.text.Image,前者将JComponent转换为图像,后者将其打印在PDF中,这个技巧被发现并基于这个peeskillet的answer

因此,如果没有进一步解释,这里是实现上述结果的代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

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

public class PdfFromUserInput {

    private JFrame frame;
    private JTextArea area;
    private JButton button;
    private Document document;
    private PdfWriter writer;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new PdfFromUserInput().createAndShowGui();
            }
        });
    }

    public void openPdf() throws FileNotFoundException, DocumentException {
        document = new Document(PageSize.A4, 30, 30, 30, 30);
        writer = PdfWriter.getInstance(document, new FileOutputStream("myFile.pdf"));
        document.open();
    }

    public void closePdf() {
        document.close();
    }

    public java.awt.Image getImageFromComponent(JComponent component) throws DocumentException {
        BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB);
        component.paint(image.getGraphics());
        return image;
    }

    public void addImageToDocument(java.awt.Image img) throws IOException, DocumentException {
        Image image = Image.getInstance(writer, img, 1);
        image.scalePercent(50);
        document.add(image);
        System.out.println("printed!");
    }

    public void createAndShowGui() {
        frame = new JFrame("PDF creator");
        area = new JTextArea(10, 30);
        area.setBorder(BorderFactory.createLineBorder(Color.RED));
        button = new JButton("Create PDF");

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    openPdf();
                    java.awt.Image img = getImageFromComponent(area);
                    addImageToDocument(img);
                    img = getImageFromComponent(button);
                    addImageToDocument(img);
                    closePdf();
                } catch (DocumentException e1) {
                    e1.printStackTrace();
                } catch (FileNotFoundException e1) {
                    e1.printStackTrace();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        });

        frame.add(area, BorderLayout.CENTER);
        frame.add(button, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}