开发者

Convert from PDF to Postscript using Java

I am having a J2EE based app开发者_如何学JAVAlication, where I am using a reporting tool to generate outputs in PDF format. I need a utility/ tool in Java which can help me convert my PDF file to postscript format so that I can print it to a printer... My application will be running on a variety of OS (i.e. Windows / Linux / AIX) hence a platform independant solution is essential. My reporting tool does not support outputs in PS format. Please advice...


There are AFAIK no fool proof pure Java solutions for this, but if the conversion is to be done server-side, I would recommend you to use Ghostscript's pdf2ps converter. Even if you have to install a platform specific version of Ghostscript, you should find one for all the mentioned platforms.


There are several PDF libraries which can print PDFs. If you print to a Postscript Printer and use the print to file option, you could end up with Postscript.


Another solution "exe based", like Ghostscript, is Xpdf.PdfToPS
PdfToPs is a pure commandline application. Runs on Win, Linux and Solaris.
http://www.foolabs.com/xpdf/


Here is my pure Java solution. It works well on CentOS, SUSE, and Windows 7. And no installation of any software is needed.

import java.io.File;
import java.io.FileOutputStream;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.SimpleDoc;
import javax.print.StreamPrintService;
import javax.print.StreamPrintServiceFactory;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;

public class Printing {


        public static void main(String[] args) {
            try {
            DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
            String psMimeType = DocFlavor.BYTE_ARRAY.POSTSCRIPT.getMimeType();
            StreamPrintServiceFactory[] factories = StreamPrintServiceFactory.lookupStreamPrintServiceFactories(flavor, psMimeType);

            System.out.println ("Available PS services: " + factories.length);
            System.out.println ("Format: " + factories[0].getOutputFormat());

            FileOutputStream outStream = new FileOutputStream("/path/to/your.ps");
            StreamPrintService printService = factories[0].getPrintService(outStream);


            PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
            aset.add(MediaSizeName.NA_LETTER);              

            PDDocument doc = PDDocument.load(new File("/path/to/my.pdf"));

            SimpleDoc pdfDoc = new SimpleDoc(new PDFPrintable(doc, Scaling.SCALE_TO_FIT, false), flavor, null);

            DocPrintJob newJob = printService.createPrintJob();
            newJob.print(pdfDoc, aset);

            outStream.close();

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

Dependency:

dependencies {
    compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.8'
}


Using fop xslfo http://xmlgraphics.apache.org/fop/fop-pdf-images.html

fop test.fo -ps out.ps

test.fo:

<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

  <fo:layout-master-set>
    <fo:simple-page-master master-name="simple">
      <fo:region-body />
    </fo:simple-page-master>
  </fo:layout-master-set>
  <fo:page-sequence master-reference="simple">
    <fo:flow flow-name="xsl-region-body">

   <fo:block>
    <fo:external-graphic src="my.pdf"/>
      </fo:block> 

    </fo:flow>
  </fo:page-sequence>
</fo:root>


Thanks, I have tried this option and very well able to convert pdf to postscript. The only problem I am facing is, when I am sending such file to printer and if the pdf is having mixed orientation like some pages in portrait and some are in landscape, then converted postscript file is getting printed either in portrait mode or in landscape mode. It should handle orientation automatically while printing.

Code snippet for print ps file -

    DocPrintJob job = service.createPrintJob();
    try {
        PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
        File psFile = new File (psFilePath); 
        InputStream inputStream = new FileInputStream(psFile);
        Doc doc = new SimpleDoc(inputStream, DocFlavor.INPUT_STREAM.POSTSCRIPT ,null);
        job.print(doc, attributes);
    } catch (Exception e) {
        e.printStackTrace();
    }


Maybe consider using jasper reports.

It will allow you to generate a report in a variety outputs (PDF, Html, RTF).

You can also export the report to a printer.

Edit:

Here is a quick example I found to export to a printer using JRPrintServiceExporter as opposed using a PDF exporter. It looks like it will do the job.


Maybe this code can help:

try
    {
        DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
        String psMimeType = DocFlavor.BYTE_ARRAY.POSTSCRIPT.getMimeType();
        StreamPrintServiceFactory[] factories = StreamPrintServiceFactory.lookupStreamPrintServiceFactories(flavor, psMimeType);

        System.out.println ("Available PS services: " + factories.length);

        if(factories.length == 0)
        {
            System.err.println ("No PS factories available!");
            System.exit(0);
        }

        // Open the PDF file
        PDFPrint pdfPrint = new PDFPrint ("test.pdf", null);

        // Open the output file
        FileOutputStream fos = new FileOutputStream("output.ps");

        // Use the first service available
        StreamPrintService sps = factories[0].getPrintService(fos);
        DocPrintJob pj = sps.createPrintJob();

        // Define paper size
        PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
        aset.add(MediaSizeName.NA_LETTER);

        // Create simple doc using PDFPrint as Printable and print it
        SimpleDoc doc = new SimpleDoc(pdfPrint, flavor, null);
        pj.print(doc, aset);

        // Close the output PS stream
        fos.close();
    }
    catch (Throwable t)
    {
        t.printStackTrace();
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜