I have a PDF form where there are check boxes given as images in the PDF. I am using itext to read the PDF, I also want to get the value of the checkbox as ticked or unticked.
iText does not return anything for the images, below is the iText code:
PdfReader reader = new PdfReader(path);
Rectangle mediaboxKeys=reader.getPageSize(i);
mediaboxKeys.setRight((float) 100.00);
RenderFilter[] filterKeys = {new RegionTextRenderFilter(mediaboxKeys)};
FilteredTextRenderListener strategyKeys = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), filterKeys);
String[] keysFromPage = PdfTextExtractor.getTextFromPage(reader, i, strategyKeys).split("\\r?\\n");
Attached is the pdf : https://drive.google.com/file/d/1D9TNnHZe5kqwv6LKIVO94Am1nl8AnrB1/view
Related
Downloaded pdf with form field from code
Adobe sign tool duplicating the form fields
I have tried creating date fields and signature fields for PDF using iText5 Library and generated the PDF. In the downloaded pdf when opened in Adobe Acrobat Reader, I see only one field created, but when the pdf is uploaded to Adobe Sign, the form fields are duplicated.
Below is my code:
Document document = new Document(PageSize.A4,40,40,60,50);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document,baos);
PdfPTable signatureTable = createPdfTable(2);
signatureTable.setWidths(new int[] {1,1});
PdfPCell signatureCell = new PdfPCell();
TextField signatureText = new TextField(writer,signatureCell,"TCSig1_es_:signer1:signature");
signatureText.setBackgroundColor(BaseColor.WHITE);
PdfFormField signField = signatureText.getTextField();
signField.setPlaceInPage(4);
FieldPositioningEvents signatureEvent = new FieldPositioningEvents(writer, signField);
signatureCell.setCellEvent(signatureEvent);
signatureTable.addCell(signatureCell);
document.add(signatureTable);
I create chart using Xchart and save it as PDF file using VectorGraphics2D as follows:
VectorGraphicsEncoder.saveVectorGraphic(chart, "chart_name", VectorGraphicsFormat.PDF);
However I need to save several charts in the same PDF file. Is there any way of doing it using iText?
ProcessingPipeline g = null;
g = new PDFGraphics2D(0.0, 0.0, chart.getWidth(), chart.getHeight());
chart.paint(g, chart.getWidth(), chart.getHeight());
FileOutputStream file1 = new FileOutputStream(addFileExtension("doc_name", VectorGraphicsFormat.PDF));
Document doc = new Document(PageSize.A4.rotate());
PdfWriter writer = PdfWriter.getInstance(doc, file1);
doc.open();
However I fail when I add the g to the document. How do I fix this?
You can save an image with desired grid in one image using :
BitmapEncoder.saveBitmap(
Arrays.asList(new Chart[]{chart1, chart2, chart3, chart4}), 2,2, "./cumulative", BitmapEncoder.BitmapFormat.PNG);
where 2,2 is the row and col size.
After getting this image with 4 charts you can export it in a PDF.
I am not getting any tutorial for adding a text watermark in a PDF file? Can you all please guide me, I am very new to PDFBOX.
Its not duplicate, the link in the comment didn't help me. I want to add text, not an image to the pdf.
Here is an example using PDFBox 2.0.2. This will load a PDF and write some text in the bottom right corner in a red transparent font. If it is a multiple page PDF the watermark will appear on every page. It might not be production ready, as I am not sure if there are some additional null conditions that need to be checked, but it should get you running in the right direction.
Keep in mind that this particular block of code will not modify the original PDF, but will create a new PDF using the Tmp_(filename) as the output.
private static void watermarkPDF (File fileStored) {
File tmpPDF;
PDDocument doc;
tmpPDF = new File(fileStored.getParent() + System.getProperty("file.separator") +"Tmp_"+fileStored.getName());
doc = PDDocument.load(fileStored);
for(PDPage page:doc.getPages()){
PDPageContentStream cs = new PDPageContentStream(doc, page, AppendMode.APPEND, true, true);
String ts = "Some sample text";
PDFont font = PDType1Font.HELVETICA_BOLD;
float fontSize = 14.0f;
PDResources resources = page.getResources();
PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
r0.setNonStrokingAlphaConstant(0.5f);
cs.setGraphicsStateParameters(r0);
cs.setNonStrokingColor(255,0,0);//Red
cs.beginText();
cs.setFont(font, fontSize);
cs.setTextMatrix(Matrix.getTranslateInstance(0f,0f));
cs.showText(ts);
cs.endText();
}
cs.close();
}
doc.save(tmpPDF);
}
I am using iText to split a PDF document into separate pages as PDF files. Each file seems to be too large as all fonts used in the input PDF are saved into all result pages, which is apparently not very clean.
Code of splitting is as below. Notice PdfSmartCopy and setFullCompression doesn't help to reduce size (which I have no idea why).
public List<byte[]> split(byte[] input) throws IOException, DocumentException {
PdfReader pdfReader = new PdfReader(input);
List<byte[]> pdfFiles = new ArrayList<>();
int pageCount = pdfReader.getNumberOfPages();
int pageIndex = 0;
while (++pageIndex <= pageCount) {
Document document = new Document(pdfReader.getPageSizeWithRotation(pageIndex));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfCopy pdfCopy = new PdfSmartCopy(document, byteArrayOutputStream);
pdfCopy.setFullCompression();
PdfImportedPage pdfImportedPage = pdfCopy.getImportedPage(pdfReader, pageIndex);
document.open();
pdfCopy.addPage(pdfImportedPage);
document.close();
pdfCopy.close();
pdfFiles.add(byteArrayOutputStream.toByteArray());
}
return pdfFiles;
}
So is there a way in Java (iText or not) to solve these problem?
Update with demo PDF
Here is a 377KB PDF using multiple CJK fonts where any page in it using 1 or 2 fonts. The summary size of sub-PDFs is 1.2MB. Considering CJK fonts are very bloated, I would like to find a way to remove unused font and even remove unused characters in used fonts.
So my idea is to remain only used characters in used fonts and embed them in sub files and then un-embed all other fonts. Any advice?
we have a PDF with some fields in order to collect some data, and I have to fill it programmatically with iText on Android by adding some text in those positions. I've been thinking about different ways to achieve this, with little success in each one.
Note: I'm using the Android version of iText (iTextG 5.5.4) and a Samsung Galaxy Note 10.1 2014 (Android 4.4) for most of my tests.
The approach I took from the start was to "draw" the text on a given coordinates, for a given page. This has some problems with the management of the fields (I have to be aware of the length of the strings, and it could be hard to position each text in the exact coordinate of the pdf). But most importantly, the performance of the process is really slow in some devices/OSVersions (it works great in Nexus 5 with 5.0.2, but takes several minutes with a 5MB Pdf on the Note 10.1).
pdfReader = new PdfReader(is);
document = new Document();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pdfCopy = new PdfCopy(document, baos);
document.open();
PdfImportedPage page;
PdfCopy.PageStamp stamp;
for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
page = pdfCopy.getImportedPage(pdfReader, i); // First page = 1
stamp = pdfCopy.createPageStamp(page);
for (int i=0; i<10; i++) {
int posX = i*50;
int posY = i*100;
Phrase phrase = new Phrase("Example text", FontFactory.getFont(FontFactory.HELVETICA, 12, BaseColor.RED));
ColumnText.showTextAligned(stamp.getOverContent(), Element.ALIGN_CENTER, phrase, posX, posY, 0);
}
stamp.alterContents();
pdfCopy.addPage(page);
}
We though about adding "forms fields" instead of drawing. That way I can configure a TextField and avoid managing the texts myself. However, the final PDF shouldn't have any annotations, so I would need to copy it into a new Pdf without annotations and with those "forms fields" drawn. I don't have an example of this because I wasn't able to perform this, I don't even know if this is possible/worthwhile.
The third option would be to receive a Pdf with the "forms fields" already added, that way I only have to fill them. However I still need to create a new Pdf with all those fields and without annotations...
I'd like to know what's be the best way in performance to do this process, and any help about achieving it. I am really newbie with iText and any help would be really appreciated.
Thanks!
EDIT
At the end I used the third option: a PDF with editable fields that we fill, and then we use the "flattening" to create a non-editable PDF with all texts already there.
The code is as follows:
pdfReader = new PdfReader(is);
FileOutputStream fios = new FileOutputStream(outPdf);
PdfStamper pdfStamper = new PdfStamper(pdfReader, fios);
//Filling the PDF (It's totally necessary that the PDF has Form fields)
fillPDF(pdfStamper);
//Setting the PDF to uneditable format
pdfStamper.setFormFlattening(true);
pdfStamper.close();
and the method to fill the forms:
public static void fillPDF(PdfStamper stamper) throws IOException, DocumentException{
//Getting the Form fields from the PDF
AcroFields form = stamper.getAcroFields();
Set<String> fields = form.getFields().keySet();
for(String field : fields){
form.setField("name", "Ernesto");
form.setField("surname", "Lage");
}
}
}
The only thing about this approach is that you need to know the name of each field in order to fill it.
There is a process in iText known as 'flattening', which takes the form fields, and replaces them with the text that the fields contain.
I haven't used iText in a few years (and not at all on Android), but if you search the manual or online examples for 'flattening', you should find how to do it.