我正在尝试使用 java.awt.print 包打印 PDF 文档。为此,我创建了一个 Printable 对象,该对象对文件进行了简短的转换(这种技术是前段时间从另一个主题派生出来的)。
private static void printDocument(File finalFile, PrintService printer, String name) throws PrinterException {
System.out.println(String.format("Starting %s document", name));
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(finalFile);
byte[] pdfContent = new byte[fileInputStream.available()];
fileInputStream.read(pdfContent, 0, fileInputStream.available());
ByteBuffer buffer = ByteBuffer.wrap(pdfContent);
final PDFFile pdfFile = new PDFFile(buffer);
//Create Printable object in preparation for printing
Printable printable = new Printable() {
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
int pagenum = pageIndex + 1;
if ((pagenum >= 1) && (pagenum <= pdfFile.getNumPages())) {
Graphics2D graphics2D = (Graphics2D) graphics;
PDFPage page = pdfFile.getPage(pagenum);
Rectangle imageArea = new Rectangle((int) pageFormat.getImageableX(), (int) pageFormat.getImageableY(),
(int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableHeight());
graphics2D.translate(0, 0);
PDFRenderer pdfRenderer = new PDFRenderer(page, graphics2D, imageArea, null, null);
try {
page.waitForFinish();
pdfRenderer.run();
}
catch (InterruptedException e) {
e.printStackTrace();
throw new PrinterException("Oh noes!");
}
return PAGE_EXISTS;
}
else {
return NO_SUCH_PAGE;
}
}
};
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintService(printer);
PageFormat pageFormat = printJob.defaultPage();
Book book = new Book();
book.append(printable, pageFormat, pdfFile.getNumPages());
printJob.setPageable(book);
Paper paper = new Paper();
paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
pageFormat.setPaper(paper);
PrintRequestAttributeSet pset = new HashPrintRequestAttributeSet();
printJob.setJobName(finalFile.getName() +
"|" + String.valueOf(1) +
"|" + ("T"));
printJob.print(pset);
}
catch (Exception e) {
e.printStackTrace();
throw new PrinterException();
}
finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(String.format("Finished %s document", name));
}
PDF 文件的某些特定情况对此转换过程 react 不佳,在 pdfRenderer.run(); 行上失败此堆栈跟踪:
java.lang.ArithmeticException: / by zero
at com.sun.pdfview.pattern.PatternType1$Type1PaintContext.getRaster(PatternType1.java:354)
at sun.java2d.pipe.AlphaPaintPipe.renderPathTile(AlphaPaintPipe.java:106)
at sun.java2d.pipe.DuctusShapeRenderer.renderTiles(DuctusShapeRenderer.java:147)
at sun.java2d.pipe.DuctusShapeRenderer.renderPath(DuctusShapeRenderer.java:100)
at sun.java2d.pipe.DuctusShapeRenderer.fill(DuctusShapeRenderer.java:50)
at sun.java2d.pipe.PixelToParallelogramConverter.fill(PixelToParallelogramConverter.java:146)
at sun.java2d.pipe.ValidatePipe.fill(ValidatePipe.java:142)
at sun.java2d.SunGraphics2D.fill(SunGraphics2D.java:2376)
at sun.print.ProxyGraphics2D.fill(ProxyGraphics2D.java:1381)
at com.sun.pdfview.pattern.PatternType1$TilingPatternPaint.fill(PatternType1.java:278)
at com.sun.pdfview.PDFRenderer.fill(PDFRenderer.java:261)
at com.sun.pdfview.PDFShapeCmd.execute(PDFShapeCmd.java:77)
at com.sun.pdfview.PDFRenderer.iterate(PDFRenderer.java:570)
at com.sun.pdfview.BaseWatchable.run(BaseWatchable.java:101)
at **MYFILEHERE**
这会导致文件中途失败,并导致文件只打印一半,甚至在文本行的中心停止。
这个错误的原因是什么?它发生在渲染过程中如此低的级别,处理单独的形状操作,我不得不相信这是我无法控制的和。 有什么方法可以让我的进程绕过损坏的数据并继续完整地呈现文档吗?
最佳答案
事实证明,正在执行的代码不是 Sun 的 Java 官方代码的一部分,正如 com.sun 包名称所暗示的那样,而是一个单独的项目强>位于here .代码是开源,允许我查看,修改this文件,并轻松地为自己构建一个新的 jar。如果可能,我也会尝试为该项目贡献我的修复。
修复只是添加一个检查以防止上述除以零错误。
原代码:
xloc %= useXStep;
yloc %= useYStep;
固定代码:
if (xstep != 0)
xloc %= useXStep;
if (ystep != 0)
yloc %= useYStep;
关于java - 导致被零除的 PDF 渲染器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20547040/