iText/flying-saucer PdfStamper using an OutputStream - java

I'm almost there (I think) on being able to render a PDF with a servlet without saving it first. I've been able to successfully set it up, but I'm stuck at trying to make the PDF open in the client's browser with a Print Dialog initially.
I've been able to send my PDF to the client successfully with the following:
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new StringBufferInputStream(buf.toString()));
OutputStream os = resp.getOutputStream();
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(doc, null);
renderer.layout();
renderer.createPDF(os);
os.close();
But, I'm not sure how to put a print dialog on open of it.
I've used this code for a physical PDF file, but I need to be able to read the contents of the OutputStream in as a byte array for input to the PdfReader (I think):
PdfReader reader = new PdfReader("a_physical_file.pdf");
PdfStamper stamper = new PdfStamper(reader, os);
stamper.setPageAction(PdfWriter.PAGE_OPEN, new PdfAction(PdfAction.PRINTDIALOG), 1);
stamper.close();
Not sure how to do this with an OutputStream rather than an actual file...
I've also created an iText chat room if you would like to post there: https://chat.stackoverflow.com/rooms/8945/itext

Warning : I use an old version of Itext, so my experience may not be applicable.
PdfReader can use a byte array. so you could use a ByteArrayOutputStream as your first output stream, then use it to get the reader, instead of a filename.
Regards
Edit : Regarding your question :
i'm doing it the others way around : i'm working on a ByteArrayOutputStream and then writing it in the response stream :
ByteArrayOutputStream out = new ByteArrayOutputStream();
// creating / modifying the pdf
...
byte[] pdfoutput = out.toByteArray();
res.setContentLength(pdfoutput.length);
res.getOutputStream().write(pdfoutput);
Edit 2 : the final solution (from the chat room)
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new StringBufferInputStream(buf.toString()));
OutputStream os = new ByteArrayOutputStream();
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(doc, null);
renderer.layout();
renderer.createPDF(os);
os.close();
PdfReader reader = new PdfReader(((ByteArrayOutputStream)os).toByteArray());
OutputStream out = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, out);
stamper.setPageAction(PdfWriter.PAGE_OPEN, new PdfAction(PdfAction.PRINTDIALOG), 1);
stamper.close();
resp.getOutputStream().write(((ByteArrayOutputStream)out).toByteArray());

Instead of using PdfStamper, why don't you implement PDFCreationListener of flyingsacuer to massage any pdf created. You can get the PdfWriter instance and set the print dialogue from within the implementation class.
From the javadoc of PDFCreationListener
PDFCreationListener is the callback listener for PDF creation. To use this, call ITextRenderer.setListener(PDFCreationListener).Note that with a handle on the ITextRenderer instance (provided in the callback arguments) you can access the com.lowagie.text.pdf.PdfWriter instance being used to create the document, using
ITextRenderer.getOutputDevice(), then calling ITextOutputDevice.getWriter().
The related thread is here.

Related

How to Read and write InputStream to a pdf file using iText?

I have an InputStream. I am trying to read the InputStream and write it to a pdf file using iText.
I tried the following :
FileOutputStream fileout = new FileOutputStream(file);
Document document = new Document();
PdfWriter.getInstance(document, fileout);
InputStream is=null;
is = myInfo.getInputStream();
String result = IOUtils.toString(is, "UTF-8");
Paragraph paragraph=new Paragraph();
paragraph.add(result);
document.add(paragraph);
is.close();
document.close();
Here the output file contains so many unwanted characters, some XML tags etc. The output pdf file is dumped with a lot of things which are non-readable.
And I am able to write it to pdf file using the following code:
OutputStream ostream = new FileOutputStream("c:\\test\\newfile1.pdf");
byte[] data = new byte[4096];
int r = 0;
while((r = is.read(data, 0, data.length)) != -1)
{
ostream.write(data, 0, r);
}
ostream.flush();
ostream.close();
The above code helps me to write the inputstream to the pdf file. But I want to do the same thing with itext.
I am using iText for the first time and confused how to use it properly. Could someone please help me with this? Thanks.
Solution :
I changed the inputstream to bytearraay.
PdfReader pdfreader;
pdfreader = new PdfReader(myInfo.getByteArray());
PdfStamper pdfStamper = new PdfStamper(pdfreader, fileout);
pdfStamper.close();
pdfreader.close();
In this way, I am able to read the inputsteam and write to pdf using itext. Thanks everyone.

How to save doc file with anchor image by using Apache POI HWPFDocument

I am using HWPFDocument to modify some doc file. However, when I try to save a new doc file with anchor image, the image will become broken. Does any method that can handle this case? Here are some my codes.
File file = new File("testdoc.doc");
FileInputStream fis = new FileInputStream(file);
POIFSFileSystem poifs = new POIFSFileSystem(fis);
HWPFDocument doc = new HWPFDocument(poifs);
FileOutputStream out = new FileOutputStream("testtt.doc");
doc.write(out);
out.close();
doc.close();
I do not modify anything of the doc file but the anchor image still become broken.

Send whole content to mail in pdf after clicking a button in jsp

I am creating a java server page.
It has a button to send an email.
After clicking the button the whole page content should be sent as a pdf to a client as an attachment.
I do not want to store this pdf on the server.
You can use iText to generate a pdf document without having to physically create a file.
example:
File out = new File("somewhere.pdf");
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileWriter(out)));
Document layoutDocument = new Document(pdfDocument);
layoutDocument.add(new Paragraph("Hello World"));
layoutDocument.close();
In this particular example I've used a FileWriter, but any Writer will do.
So
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Writer w = new OutputStreamWriter(baos);
// iText logic here
...
// add bytes to email
byte[] mimeBytes = baos.toByteArray();
...
Check out the documentation for iText at http://developers.itextpdf.com/content/itext-7-jump-start-tutorial/examples

using apache fop with PipedOutputStream

I want to build a pdf-file from a jaxb-object using apache fop to generate and itext PdfStamper to modify it. since fop writes to an outputStream and PdfStamper reads from InputStream my idea was to use Piped[I|O]Streams for this. here is what I tried:
public void transform2XSLFO_onthefly(Medium medium, OutputStream out) throws Exception {
PipedInputStream pInputPipe = new PipedInputStream();
PipedOutputStream outputTemp = new PipedOutputStream(pInputPipe);
try {
JAXBSource source = new JAXBSource( JAXBContext.newInstance(medium.getClass()) , medium );
FOUserAgent userAgent = fopFactory.newFOUserAgent();
// settings
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent ,outputTemp);
InputStream XSLinputStream = xslfoStylesheet.getInputStream();
StreamSource XSLsource = new StreamSource(XSLinputStream);
Result res = new SAXResult(fop.getDefaultHandler());
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer(XSLsource);
// run transformation
t.transform(source, res);
// does not come so far, no use closing the stream
outputTemp.close();
PdfReader reader = new PdfReader(pInputPipe);
pdfStamper = new PdfStamper(reader, out);
//..... postProcess...
pdfStamper.close();
} catch (Exception ex) {
log.error("ERROR", ex);
}
However it hangs in the line "t.transform(source, res);", looks like he is waiting for something in the middle of the fop-transformation. It works using BypeArrayOutputStream and convert it to inputstream and use it for PdfStamper input:
InputStream pdfInput = new ByteArrayInputStream(((ByteArrayOutputStream) outputTemp).toByteArray());
but the files can get quite large (few MB) so i think the piped version would perform better! what do you think?
You should read up on how to use PipeInput/OutputStream. FOP and the PdfStamper will need to run in separate threads. Basically, this has nothing to do with FOP per se. I'm sure you'll find various examples on the net on how this works. If you're not comfortable with multi-threaded programming, I suggest you just buffer FOP's output in a byte[] or a temporary file.

xhtmlrenderer xhtml to pdf font problem

I'm using org.xhtmlrenderer.pdf.ITextRenderer to convert my (x)html page to pdf using Java.
I've got most of it working, except the font part.
I'm using verdana in my page and the pdf is rendered using default font.
I have added the verdana.ttf to my jar and use the following code:
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new StringBufferInputStream(html));
File tmpFontFile = new File(TEMP_FOLDER + "/verdana.ttf");
if(!tmpFontFile.exists())
{
tmpFontFile.createNewFile();
InputStream fontIs = getClass().getResourceAsStream("/com/mycompany/util/font/verdana.ttf");
OutputStream fontOs = new FileOutputStream(tmpFontFile);
byte buf[] = new byte[1024];
int len;
while((len = fontIs.read(buf)) > 0)
fontOs.write(buf,0,len);
fontOs.close();
fontIs.close();
}
ITextRenderer renderer = new ITextRenderer();
renderer.getFontResolver().addFont(
tmpFontFile.getAbsolutePath(), BaseFont.IDENTITY_H ,BaseFont.EMBEDDED);
renderer.setDocument(doc, null);
String outputFile = TEMP_FOLDER + "/mypdf.pdf";
OutputStream os = new FileOutputStream(outputFile);
renderer.layout();
renderer.createPDF(os);
os.close();
What am I missing here?
Thanks,
Bart
For xhtmlrenderer to work, the CSS must read:
font-family: Verdana;
instead of
font-family:verdana;
It's case-sensitive.

Categories

Resources