我正在處理一個用戶故事,要求能夠將所有現有的打印輸出爲PDF文件。要做到這一點,我渲染java.awt.Printable
到BufferedImage
並把這個圖像到使用Apache的一個PDFBox的PDF,但我有一對夫婦使用這種方法的問題:將可打印文件轉換爲PDF
- 如果我使用
PDJPeg
圖像變得模糊。 - 如果我使用
PDPixelMap
,則生成的PDF是完全黑色的。
我能想到的唯一的另一種方法是做一個接口,即Printer
,然後做兩個子類,即PhysicalPrinter
和PDFPrinter
但這需要我重新實現所有現有java.awt.Printable
s到使用這個新的接口。
這裏是我當前的打印到PDF方法SSCCE:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.io.File;
import java.util.Random;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
public class Printer {
private Printer() {}
public static boolean printToPDF(String file, Printable printable) {
try {
PageFormat pageFormat = new PageFormat();
PDDocument doc = new PDDocument();
int width = (int)(pageFormat.getWidth());
int height = (int)(pageFormat.getHeight());
int currentPage = 0;
while(true) {
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.BLACK);
g2d.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
if(printable.print(g2d, pageFormat, currentPage) == Printable.NO_SUCH_PAGE) {
break;
}
ImageIO.write(image, "png", new File("test.png"));
PDPage page = new PDPage();
doc.addPage(page);
PDJpeg img = new PDJpeg(doc, image); //Blurry
//PDPixelMap img = new PDPixelMap(doc, image); //Black
PDPageContentStream content = new PDPageContentStream(doc, page);
content.drawImage(img, 0, 0);
content.close();
++currentPage;
}
doc.save(file);
doc.close();
} catch(Exception e) {
e.printStackTrace();
}
return true;
}
public static void main(String[] args) {
Printable printable = new Printable() {
@Override
public int print(Graphics g, PageFormat pf, int index)
throws PrinterException {
if(index > 0) {
return NO_SUCH_PAGE;
}
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
Random rand = new Random();
for(int i = 0; i < 30; ++i) {
int x = rand.nextInt((int)pf.getImageableWidth());
int y = rand.nextInt((int)pf.getImageableHeight());
g2d.drawString("Test", x, y);
}
return PAGE_EXISTS;
}
};
printToPDF("Test.pdf", printable);
}
}
編輯
我設法解決黑PDPixelMap
,則下跌至BUfferedImage
使用錯誤圖像類型。我將它從BufferedImage.TYPE_INT_RGB
更改爲BufferedImage.TYPE_4BYTE_ABGR
。不幸的是,由此產生的PDF仍然是模糊的。
此問題將在即將發佈的1.8.5版本中修復,請參閱https://issues.apache.org/jira/browse/PDFBOX-2030。它已經在2.0版本(具有不同的API)中得到修復,請參閱https://issues.apache.org/jira/browse/PDFBOX-1990。你可以從svn獲得兩個。 –