Create PDFReader from String or InputStream - java

Below is my code to create PDF from input String or byte[]
This input is working with iText5. When I pass input to PdfReader in iText5 it was able to create PdfReader object.
Case 1:
byte[] bytesDecoded = Base64.decodeBase64(input.getBytes(StandardCharsets.UTF_8));
InputStream is = IOUtils.toInputStream(bytesDecoded.toString(), StandardCharsets.UTF_8);
PdfReader reader = new PdfReader(is);
Case 2:
PdfReader reader = new PdfReader(IOUtils.toInputStream(input, StandardCharsets.UTF_16));
Exception:
Exception in thread "main" com.itextpdf.io.IOException: PDF header not found.
at com.itextpdf.io.source.PdfTokenizer.getHeaderOffset(PdfTokenizer.java:223)
at com.itextpdf.kernel.pdf.PdfReader.getOffsetTokeniser(PdfReader.java:1018)
Not working in iText7

This is the way I have done. Sharing it as may be useful in future.
ByteArrayOutputStream pdfos = new ByteArrayOutputStream();
byte[] bytesDecoded = Base64.decodeBase64(src.getBytes(StandardCharsets.UTF_8));
ByteArrayInputStream inStream = new ByteArrayInputStream(bytesDecoded);
PdfReader reader = new PdfReader(inStream);
PdfSigner signer = new PdfSigner(reader, pdfos, false);

This is the easiest method to create a PdfReader from a Byte[] or a String.
byte[] template;
PdfReader templatePdf = new PdfReader(new RandomAccessSourceFactory().CreateSource(new MemoryStream(template).ToArray()),new ReaderProperties());

Related

how to convert png to svg using apache batik in java?

i want to convert my png image file into svg and store in file system, i not found any apropriate answer if anyone have the solution please share.
i use below code but not work
SVGTranscoder t = new SVGTranscoder();
t.addTranscodingHint(SVGTranscoder.KEY_FORMAT, true);
String svgURI = new File(inputFilePath).toURL().toString();
InputStream inputStream = new FileInputStream(inputFilePath);
Reader inputStreamReader = new InputStreamReader(inputStream);
TranscoderInput input = new TranscoderInput(inputStreamReader);
OutputStream ostream = new FileOutputStream(outputFilePath);
Writer outputStreamWriter = new OutputStreamWriter(ostream);
TranscoderOutput output = new TranscoderOutput(outputStreamWriter);
t.transcode(input, output);
ostream.flush();
ostream.close();
System.exit(0);
Try this:
Converter converter = new Converter("input.png");
// Prepare conversion options for target format SVG
ConvertOptions convertOptions = new FileType().fromExtension("svg").getConvertOptions();
// Convert to SVG format
converter.convert("output.svg", convertOptions);

iText 7 Html to Pdf conversion and linking external file to the generated pdf

I am encountering an issue while merging two PDFs generated out of IText.
I am new to iText7
I am creating one pdf from html and creating another pdf with excel(.xls) as embedded document to pdf.
I want to merge the 2 files.
Basically I want to generate a PDF from html then attach a excel document to it and then output combined html outPutStream from these two pdfs.
Below is the code I am using
ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(htmlToPdfContent);
PdfDocument pdf = new PdfDocument(writer);
pdf.setTagged();
PageSize pageSize = PageSize.A4.rotate();
pdf.setDefaultPageSize(pageSize);
ConverterProperties properties = new ConverterProperties();
HtmlConverter.convertToPdf(htmlContent, pdf, properties);
FileUtils.cleanDirectory(new File(outputDir));
ByteArrayOutputStream pdfResult = new ByteArrayOutputStream();
PdfWriter writerResult = new PdfWriter(pdfResult);
PdfDocument pdfDocResult = new PdfDocument(writerResult);
PdfReader reader = new PdfReader(new ByteArrayInputStream(htmlToPdfContent.toByteArray()));
PdfDocument pdfDoc = new PdfDocument(reader);
pdfDoc.copyPagesTo(1, pdfDoc.getNumberOfPages(), pdfDocResult);
ByteArrayOutputStream pdfAttach = new ByteArrayOutputStream();
PdfDocument pdfLaunch = new PdfDocument(new PdfWriter(pdfAttach));
Rectangle rect = new Rectangle(36, 700, 100, 100);
byte[] embeddedFileContentBytes = Files.readAllBytes(Paths.get(excelPath));
PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec(pdfLaunch, embeddedFileContentBytes, null, "test.xlsx", null, null);
PdfAnnotation attachment = new PdfFileAttachmentAnnotation(rect, fs)
.setContents("Click me");
pdfLaunch.addNewPage().addAnnotation(attachment);
PdfDocument appliedChanges = new PdfDocument(new PdfReader(new ByteArrayInputStream(pdfAttach.toByteArray())));
appliedChanges.copyPagesTo(1, appliedChanges.getNumberOfPages(), pdfDocResult);
try(OutputStream outputStream = new FileOutputStream(dest)) {
pdfResult.writeTo(outputStream);
}
This is throwing exception
13:56:05.724 [main] ERROR com.itextpdf.kernel.pdf.PdfReader - Error occurred while reading cross reference table. Cross reference table will be rebuilt.
com.itextpdf.io.IOException: Error at file pointer 19,272.
at com.itextpdf.io.source.PdfTokenizer.throwError(PdfTokenizer.java:678)
at com.itextpdf.kernel.pdf.PdfReader.readXrefSection(PdfReader.java:801)
at com.itextpdf.kernel.pdf.PdfReader.readXref(PdfReader.java:774)
at com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:538)
at com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1818)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:238)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:221)
at com.mediaocean.prisma.order.command.infrastructure.pdf.itext.PdfAttachmentLaunch.main(PdfAttachmentLaunch.java:76)
Caused by: com.itextpdf.io.IOException: xref subsection not found.
... 8 common frames omitted
Exception in thread "main" com.itextpdf.kernel.PdfException: Trailer not found.
at com.itextpdf.kernel.pdf.PdfReader.rebuildXref(PdfReader.java:1064)
at com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:543)
at com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1818)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:238)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:221)
at com.mediaocean.prisma.order.command.infrastructure.pdf.itext.PdfAttachmentLaunch.main(PdfAttachmentLaunch.java:88)
13:56:05.773 [main] ERROR com.itextpdf.kernel.pdf.PdfReader - Error occurred while reading cross reference table. Cross reference table will be rebuilt.
com.itextpdf.io.IOException: PDF startxref not found.
at com.itextpdf.io.source.PdfTokenizer.getStartxref(PdfTokenizer.java:262)
at com.itextpdf.kernel.pdf.PdfReader.readXref(PdfReader.java:753)
at com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:538)
at com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1818)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:238)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:221)
at com.mediaocean.prisma.order.command.infrastructure.pdf.itext.PdfAttachmentLaunch.main(PdfAttachmentLaunch.java:88)
Please advise. Thanks in advance !!
Concerning revision 2 of your question
You changed your code differently than proposed in my answer to the first revision of your question, you now convert into the formerly unused PdfDocument pdf instead of directly into the ByteArrayOutputStream htmlToPdfContent.
This actually also is a possible fix of the problem identified in that answer. Thus, you don't get an exception here anymore:
PdfReader reader = new PdfReader(new ByteArrayInputStream(htmlToPdfContent.toByteArray()));
PdfDocument pdfDoc = new PdfDocument(reader);
Instead you now get an exception further down the flow, here:
PdfDocument appliedChanges = new PdfDocument(new PdfReader(new ByteArrayInputStream(pdfAttach.toByteArray())));
And the reason is simple, you have not yet closed the PdfDocument pdfLaunch which writes to the ByteArrayOutputStream pdfAttach. But only closing finalizes the PDF in the output stream. Thus, add the close():
ByteArrayOutputStream pdfAttach = new ByteArrayOutputStream();
PdfDocument pdfLaunch = new PdfDocument(new PdfWriter(pdfAttach));
[...]
pdfLaunch.addNewPage().addAnnotation(attachment);
pdfLaunch.close(); //<==== added
PdfDocument appliedChanges = new PdfDocument(new PdfReader(new ByteArrayInputStream(pdfAttach.toByteArray())));
And you actually do the same mistake again, shortly after, you store the contents of the ByteArrayOutputStream pdfResult to outputStream without closing the PdfDocument pdfDocResult which writes to pdfResult. Thus, also add a close call there:
appliedChanges.copyPagesTo(1, appliedChanges.getNumberOfPages(), pdfDocResult);
pdfDocResult.close(); //<==== added
try(OutputStream outputStream = new FileOutputStream(dest)) {
pdfResult.writeTo(outputStream);
}
Concerning revision 1 of your question
You use the ByteArrayOutputStream htmlToPdfContent as target of two distinct PDF generators, the PdfDocument pdf via the PdfWriter writer and the HtmlConverter.convertToPdf call:
ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(htmlToPdfContent);
PdfDocument pdf = new PdfDocument(writer);
pdf.setTagged();
PageSize pageSize = PageSize.A4.rotate();
pdf.setDefaultPageSize(pageSize);
ConverterProperties properties = new ConverterProperties();
HtmlConverter.convertToPdf(content, htmlToPdfContent, properties);
This makes the content of htmlToPdfContent a hodgepodge of the outputs of both of them, in particular not a valid PDF.
As you don't add any content to pdf, you can safely remove it and reduce the above excerpt to
ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStream();
ConverterProperties properties = new ConverterProperties();
HtmlConverter.convertToPdf(content, htmlToPdfContent, properties);

Save pdf to bytearray using itext in Java

I am using itext to read a large pdf file and save selected pages.
PdfReader reader = null;
reader = new PdfReader("customPath/largePdf.pdf");
int pages = reader.getNumberOfPages();
List<Integer> pagesList = new ArrayList<Integer>();
pagesList.add(1);
pagesList.add(2);
reader.selectPages(pagesList);
String path;
PdfStamper stamper = null;
path = String.format("customerPath/split.pdf");
stamper = new PdfStamper(reader, new FileOutputStream(path));
All good until now, i can open the split.pdf .
Now, Instead of saving to a file, i want to save it to a bytearray (so that i can save it as a blob later)
Tried this:
PdfReader reader = null;
reader = new PdfReader("customPath/largePdf.pdf");
int pages = reader.getNumberOfPages();
List<Integer> pagesList = new ArrayList<Integer>();
pagesList.add(1);
pagesList.add(2);
reader.selectPages(pagesList);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper stamper2 = new PdfStamper(reader, baos);
byte[] byteARy = baos.toByteArray();
Just to make sure it works, i tried writing this bytearray to a file:
OutputStream out = new FileOutputStream("customPath/fromByteArray.pdf");
out.write(byteARy);
out.close();
fromByteArray.pdf does not open and the size is zero, any idea what might be wrong ?
You retrieve the byte array (using baos.toByteArray()) immediately after creating the PdfStamper.
PdfStamper stamper2 = new PdfStamper(reader, baos);
byte[] byteARy = baos.toByteArray();
At that time there is (next to) nothing in the output. You must instead wait until after closing your PdfStamper to retrieve the output.
PdfStamper stamper2 = new PdfStamper(reader, baos);
...
stamper2.close();
byte[] byteARy = baos.toByteArray();
Now the byte array should contain the complete, stamped PDF.

Delete pdf pages in java with iTextpdf

I have an existing function to show pdf files that I can't change.
The input of function is an InputStream variable.
In the past they used to pass a pdf file to it and it shows it.
But right now they asked me to show only first 30 pages of the pdf. So I am using iTextpdf and I do something like this:
PdfReader reader = new PdfReader (inputStream);
reader.selectPages("1-30");
Now I should send the result as InputStream variable to show method.
How I should do it?
Thanks
You can store the result using a PdfStamper like this:
PdfReader reader = new PdfReader (inputStream);
reader.selectPages("1-30");
ByteArrayOutputStream os = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, os);
stamper.close();
byte[] changedPdf = os.toByteArray();
If you want the result again to be in the InputStream inputStream variable, simply add a line
inputStream = new ByteArrayInputStream(changedPdf);
Get the reader of existing pdf file by
PdfReader pdfReader = new PdfReader("source pdf file path");
Now update the reader by
reader.selectPages("1-5,15-20");
then get the pdf stamper object to write the changes into a file by
PdfStamper pdfStamper = new PdfStamper(pdfReader,
new FileOutputStream("destination pdf file path"));
close the PdfStamper by
pdfStamper.close();
It will close the PdfReader too.

DocuSign Base64 PDF Conversion issue

I got a Bad Request:400 error while sending base 64 PDF bytes to
DocuSign SOAP API(createAndSendEnvelope). Please help me in this issue.
Below is the code for converting PDF file into base 64 bytes:
File fFile = new File(pDFFileName);
byte[] bBytes = FileUtils.readFileToByteArray(fFile);
byte[] bBytesEnc = Base64.getEncoder().encode(bBytes);
documents.setPDFBytes(bBytesEnc);
I don't think you need to do Base64 of the byte array. I have below code without base64 and its working fine for me:
File f = new File(pDFFileName);
FileInputStream fs = new FileInputStream(f);
byte[] pdfBytes = new byte[(int) f.length()];
fs.read(pdfBytes);
fs.close();
Document doc = new Document();
doc.setPDFBytes(pdfBytes);
byte[] fileBytes = System.IO.File.ReadAllBytes(#"C:\Users\%username%\Desktop\File.PDF");
// Add a document to the envelope
Document doc = new Document();
doc.DocumentBase64 = System.Convert.ToBase64String(fileBytes);
doc.Name = "TestFile.pdf";
doc.DocumentId = "3";
I do this like that and it's workinf for me.

Categories