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.
Related
I want to convert plain string to pdf document byte array in memory.
I have created a file in disc and reading back from memory. How can we do it without creating a file.
Below is the code:
//Create Document instance.
Document document = new Document();
//Create pdf file
File file = getFileFromResource(fileName);
//Create OutputStream instance.
OutputStream outputStream = new FileOutputStream(file);
//Create PDFWriter instance.
PdfWriter.getInstance(document, outputStream);
//Open the document.
document.open();
//Add content to the document.
document.add(new Paragraph(message));
//Close document and outputStream.
document.close();
outputStream.close();
//Read pdf file and convert to byte array
PdfReader reader = new PdfReader(file.getAbsolutePath());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper stamper2 = new PdfStamper(reader, baos);
stamper2.close();
byte[] bytes = baos.toByteArray();
baos.close();
reader.close();
return bytes;
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.
I'm currently converting docx to pdf, then encrypting the pdf. Here is my code:
//Convert
XWPFDocument document = new XWPFDocument(inStream);
PdfOptions options = PdfOptions.create();
PdfConverter.getInstance().convert(document, outStream, options);
//Encrypt
PdfReader reader = new PdfReader("C:\\uploads\\Resume.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("C:\\uploads\\ResumeEncrypt.pdf"));
stamper.setEncryption("hello123".getBytes(), "hello".getBytes(),
PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128 | PdfWriter.DO_NOT_ENCRYPT_METADATA);
stamper.close();
reader.close();
By doing this I am getting 2 files.
What is happening is first I converted the Resume.docx to Resume.pdf, then encrypted the Resume.pdf to ResumeEncrypt.pdf, resulting to 2 files
This is the example -
But I want only one file, that is already converted and encrypted.
This is the example of what I want -
Is it possible to get a single file after converting and encrypting ?
Try use ByteArrayInputStream, give convert pdf.
I made something similar few days ago. Convert Base64 to Gzip and unzip to xml in stream if you want i can give you that code like tip.
So maaybe you can base on this code
//Convert Based64, unzip to xml in stream (strLista is list of Base64 bytes
ByteArrayInputStream in = new ByteArrayInputStream(strLista.getBytes());
try(InputStream reader = Base64.getMimeDecoder().wrap(in)){
try (GZIPInputStream gis = new GZIPInputStream(reader)) {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()){
int readGis = 0;
while ((readGis = gis.read(buff)) > 0)
out.write(buff, 0, readGis);
I created a pdf using the iText 2.1.7 library. The Pdf (barcodes.pdf) contains a barcode with some text at the bottom. Additionally I saved this barcode as an image (barcode.png), however then the text at bottom is lost.
How do I create the barcode image which also contains the text at bottom?
String RESULT = "c:/BarCodeQRCodeGenerator/barcodes.pdf";
Document document = new Document(new Rectangle(340, 842));
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
document.open();
PdfContentByte cb = writer.getDirectContent();
document.add(new Paragraph("Barcode 128"));
Barcode128 code128 = new Barcode128();
code128.setCode("1234567890");
Image image = code128.createImageWithBarcode(cb, null, null)
document.add(image);
java.awt.Image rawImage = code128.createAwtImage(Color.BLACK, Color.WHITE);
BufferedImage outImage = new BufferedImage(rawImage.getWidth(null), rawImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
outImage.getGraphics().drawImage(rawImage, 0, 0, null);
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ImageIO.write(outImage, "png", bytesOut);
bytesOut.flush();
byte[] pngImageData = bytesOut.toByteArray();
FileOutputStream fos = new FileOutputStream("c:/BarCodeQRCodeGenerator/barcode.png");
fos.write(pngImageData);
fos.close();
In your code you forgot to close the document. The solution is not so easy using the plain iText classes. Thus I used barcode4j (to test the example you need to download it and put it in your classpath):
Code128Bean code128 = new Code128Bean();
code128.setHeight(15f);
code128.setModuleWidth(0.3);
code128.setQuietZone(10);
code128.doQuietZone(true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", 300, BufferedImage.TYPE_BYTE_BINARY, false, 0);
code128.generateBarcode(canvas, "1234567890");
canvas.finish();
//write to png file
FileOutputStream fos = new FileOutputStream("barcode.png");
fos.write(baos.toByteArray());
fos.flush();
fos.close();
//write to pdf
Image png = Image.getInstance(baos.toByteArray());
png.setAbsolutePosition(400, 685);
png.scalePercent(25);
Document document = new Document(new Rectangle(595, 842));
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("barcodes.pdf"));
document.open();
document.add(png);
document.close();
writer.close();
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.