Show formatted number and save double value - java

I have seen PDF forms where you could write numbers in your local format and the PDF stored double values in the background which could be read with PDFBox.
How can I tell the field in my example e.g. take the number 125.5 (double) and show "125,5" (my locale)?
And when the user edits the field, the value in the background still is a valid double. Is there some built in mechanism or how can a workaround look like? Thanks in advance.
public final class CreateSimpleForm
{
private static final PDFont FONT = PDType1Font.HELVETICA;
private static final float FONT_SIZE = 12;
private CreateSimpleForm()
{
}
public static void main(String[] args) throws IOException
{
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
PDResources resources = new PDResources();
resources.put(COSName.getPDFName("Helv"), FONT);
PDAcroForm acroForm = new PDAcroForm(document);
document.getDocumentCatalog().setAcroForm(acroForm);
acroForm.setDefaultResources(resources);
String defaultAppearanceString = "/Helv 0 Tf 0 g";
acroForm.setDefaultAppearance(defaultAppearanceString);
PDTextField textBox = new PDTextField(acroForm);
textBox.setPartialName("SampleField");
defaultAppearanceString = "/Helv " + FONT_SIZE + " Tf 0 0 0 rg";
textBox.setDefaultAppearance(defaultAppearanceString);
acroForm.getFields().add(textBox);
PDAnnotationWidget widget = textBox.getWidgets().get(0);
PDRectangle rect = new PDRectangle(50, 750, 200, 50);
widget.setRectangle(rect);
widget.setPage(page);
widget.setPrinted(true);
page.getAnnotations().add(widget);
textBox.setValue("Sample field");
document.save("test.pdf");
document.close();
}
}

I don't know if this is the best way but for now I'll leave it like that until someone comes up with a better solution.
I create my visible field with the UI representation and a hidden field with the "background" value which is formatted by javascript everytime I edit the visible field.
When I try to read the data I have to omit the visible fields and concentrate on the hidden ones.
This is the simplest solution for me (which of course needs to be cleaned up a bit)
public final class CreateSimpleForm {
private static final PDFont FONT = PDType1Font.HELVETICA;
private PDAcroForm acroForm;
private String defaultAppearanceString;
private PDPage page;
public static void main(String[] args) throws IOException {
new CreateSimpleForm();
}
private CreateSimpleForm() throws IOException {
PDDocument document = new PDDocument();
page = new PDPage(PDRectangle.A4);
document.addPage(page);
PDResources resources = new PDResources();
resources.put(COSName.getPDFName("Helv"), FONT);
acroForm = new PDAcroForm(document);
document.getDocumentCatalog().setAcroForm(acroForm);
acroForm.setDefaultResources(resources);
defaultAppearanceString = "/Helv 0 Tf 0 g";
acroForm.setDefaultAppearance(defaultAppearanceString);
createFormattedField("myField", 125.5);
document.save("test.pdf");
document.close();
}
private void createFormattedField(String name, Double value) throws IOException {
String nameHidden = name + "_hidden";
PDTextField textBox = createField(name, false);
textBox.setValue(String.format("%1$,.2f", value));
createField(name + "_hidden", true).setValue(value.toString());
PDActionJavaScript tfJs = new PDActionJavaScript("this.getField(\"" + nameHidden + "\").value = this.getField(\"" + name + "\").value.replace(/\\./g,'').replace(/\\,/g,'.');");
PDAnnotationAdditionalActions actions = new PDAnnotationAdditionalActions();
actions.setPC(tfJs);
actions.setBl(tfJs);
textBox.getWidgets().get(0).setActions(actions);
}
private PDTextField createField(String name, boolean hidden) throws IOException {
PDTextField textBox = new PDTextField(acroForm);
textBox.setPartialName(name);
textBox.setDefaultAppearance(defaultAppearanceString);
acroForm.getFields().add(textBox);
PDAnnotationWidget widget = textBox.getWidgets().get(0);
PDRectangle rect = new PDRectangle(50, 750, 200, 50);
widget.setRectangle(rect);
widget.setPage(page);
widget.setPrinted(true);
page.getAnnotations().add(widget);
widget.setHidden(hidden);
return textBox;
}
}

Related

Different Leading for specific page in itext 7

I can set diferent setFixedLeading on specific page.
First i add All paragraphs in list then with help recursive i calculate e height of each paragraph and compare with document height, then i add it to div.
But it dont work.
Maybe there is another way?
public static void main(String[] args) throws FileNotFoundException {
PdfDocument pdf = new PdfDocument(new PdfWriter(DEST));
Document document = new Document(pdf);
pdf.setDefaultPageSize(PageSize.A5);
float bottomMarin = 0;
document.setMargins(0, 25, bottomMarin, 25);
Div div = new Div();
div.setPadding(0);
div.setMargin(0);
maxHeight = document.getPdfDocument().getDefaultPageSize().getHeight()- bottomMarin ;/* (mainPdf_model.getLeftMargin() +mainPdf_model.getRightMargin());*/
String line = "Hello! Welcome to iTextPdf";
List<Paragraph> paragraphs = new ArrayList<>();
for (int i = 0; i < 130; i++) {
Paragraph element = new Paragraph();
element.add(line + " " + i);
element.setMargin(0);
element.setPadding(0);
element.setFixedLeading(100);
paragraphs.add(element);
}
getListParagraphOnPage(paragraphs, document, 1);
Map<Integer, List<Paragraph>> listParagraphOnPage = paragraph;
listParagraphOnPage.forEach((k,v)->{
if(k ==1){
for(Paragraph paragraph : v){
paragraph.setFixedLeading(120);
paragraph.setBackgroundColor(red);
div.add(paragraph);
}
}
if(k ==2){
for(Paragraph paragraph : v){
paragraph.setFixedLeading(150);
paragraph.setBackgroundColor(yellow);
div.add(paragraph);
}
}
if(k ==3){
for(Paragraph paragraph : v){
paragraph.setFixedLeading(30);
paragraph.setBackgroundColor(green);
div.add(paragraph);
}
}
});
Map<Integer, List<Paragraph>> paragraph = new HashMap<>();
document.add(div);
document.close();
}
static Map<Integer,List<Paragraph>> paragraph = new HashMap<>();
//This is a method that is created in the map, in which paragraphs are placed with a certain Leading
public static Map<Integer,List<Paragraph>> getListParagraphOnPage(List<Paragraph> paragraphs, Document document,int page){
float height = 0;
List<Paragraph> ps = new ArrayList<>();
for(Paragraph par: paragraphs){
if(page==1){
par.setFixedLeading(120);
}else if(page==2){
par.setFixedLeading(150);
}else if(page==3){
par.setFixedLeading(30);
}
IRenderer rendererSubTree = par.createRendererSubTree();
LayoutResult result = rendererSubTree.setParent(document.getRenderer()).
layout(new LayoutContext(new LayoutArea(1, new Rectangle(10000, 1000))));
height+=result.getOccupiedArea().getBBox().getHeight();
if(height<maxHeight){
ps.add(par);
}else {
var pageCurrent = page;
paragraph.put(page,ps);
int size = paragraph.get(pageCurrent).size();
page++;
return getListParagraphOnPage(paragraphs.subList(size,paragraphs.size()),document,page);
}
}
return paragraph;
}

iText 5 - Add empty signature field to a digitally signed document without breaking the sign

I'm trying to add an empty signature field to an existing digitally signed pdf (certify signature).
I have a workflow where many users will sign the document (approval signature), the document is created with "n" empty signature fields, one for each user, our application first apply a invisible certify signature, then each user can sign the document in respective field, but due to changes unexpected in the workflow, other users might want to sign, so we want to add the respective empty signature field and then apply the signature.
I tried to add the empty field (a table with a cell event) to the certified document but when I want to add it and associate the field, it breaks the signature, I cannot make it work correctly.
Here is the methods used to sign,add signature field, and set the signature field options.
I don't know what I'm doing wrong.
public static String sign(SignRequest signRequest, File certificate, File unsignedDocument, File image, File icon)
throws FileNotFoundException, IOException, DocumentException, StreamParsingException, OCSPException,
OperatorException, URISyntaxException, WriterException, GeneralSecurityException, FontFormatException {
SignatureType sigType = Optional
.ofNullable(SignatureType.get(signRequest.getSignatureProperties().getSignatureType()))
.orElse(SignatureType.APPROVAL_SIGNATURE);
File signedDocument = File.createTempFile("signed",".pdf");
char[] pass = signRequest.getKeyStore().getPassword().toCharArray();
// Load certificate chain
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
KeyStore ks = KeyStore.getInstance("PKCS12", provider.getName());
ks.load(new FileInputStream(certificate.getAbsolutePath()), pass);
String alias = getAliasFromKeyStore(ks);
PrivateKey pk = (PrivateKey) ks.getKey(alias, pass);
Certificate[] chain = ks.getCertificateChain(alias);
// Creating the reader and the stamper
PdfReader reader = new PdfReader(FileUtils.openInputStream(unsignedDocument));
FileOutputStream os = new FileOutputStream(signedDocument);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null, true);
PdfSignatureAppearance appearance = null;
// Certify o approval signature (approval is the default signature type)
switch (sigType) {
case CERTIFY_SIGNATURE:
if (reader.getAcroFields().getSignatureNames().size() <= 0) {
appearance = setSignatureFieldOptions(stamper.getSignatureAppearance(), reader, chain,
signRequest, image, icon, Boolean.TRUE);
} else {
appearance = setSignatureFieldOptions(stamper.getSignatureAppearance(), reader, chain,
signRequest, image, icon, Boolean.FALSE);
}
break;
case APPROVAL_SIGNATURE:
default:
appearance = setSignatureFieldOptions(stamper.getSignatureAppearance(), reader, chain, signRequest,
image, icon, Boolean.FALSE);
break;
}
// Adding LTV (optional)
OcspClient ocspClient = null;
List<CrlClient> crlList = null;
if (signRequest.getSignatureProperties().getLtv() == Boolean.TRUE) {
ocspClient = new OcspClientBouncyCastle(new OCSPVerifier(null, null));
CrlClient crlClient = new CrlClientOnline(chain);
crlList = new ArrayList<CrlClient>();
crlList.add(crlClient);
}
// Adding timestamp (optional)
TSAClient tsaClient = null;
if (signRequest.getTimestamp() != null
&& StringUtils.isNotBlank(signRequest.getTimestamp().getUrl())) {
tsaClient = new TSAClientBouncyCastle(signRequest.getTimestamp().getUrl(),
signRequest.getTimestamp().getUser(), signRequest.getTimestamp().getPassword());
}
// Creating the signature
ExternalSignature pks = new PrivateKeySignature(pk, signtRequest.getSignatureProperties().getAlgorithm(),
provider.getName());
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature
.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient,
calculateEstimatedSize(chain, ocspClient, tsaClient, crlList, getEstimatedSizeBonus()), CryptoStandard.CMS);
return signedDocument.getAbsolutePath();
}
private static PdfSignatureAppearance setSignatureFieldOptions(PdfSignatureAppearance appearance, PdfReader reader, Certificate[] chain, SignRequest signRequest, File image, File icon, Boolean certifySignature) throws MalformedURLException, IOException, DocumentException {
SignatureProperties sigProperties = signRequest.getSignatureProperties();
SignatureField sigField = sigProperties.getSignatureField();
// Creating the appearance
appearance.setSignatureCreator(Constant.SIGNATURE_CREATOR);
Optional.ofNullable(sigProperties.getReason()).ifPresent(appearance::setReason);
Optional.ofNullable(sigProperties.getLocation()).ifPresent(appearance::setLocation);
if (certifySignature) {
appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);
} else {
appearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
}
/**
* Signature Field Name
*/
BoundingBox box = sigProperties.getSignatureField().getBoundingBox();
String fieldName = sigField.getName();
int pageNumber = sigProperties.getSignatureField().getPage();
if (!sigField.isVisible()) {
if (StringUtils.isBlank(sigField.getName())) {
fieldName = generateFieldName();
appearance.setVisibleSignature(new Rectangle(0, 0, 0, 0), pageNumber, fieldName);
} else {
appearance.setVisibleSignature(new Rectangle(0, 0, 0, 0), pageNumber, fieldName);
}
} else {
Font font = FontFactory.getFont(Optional.ofNullable(sigField.getFontName()).orElse(BaseFont.HELVETICA),
Optional.ofNullable(sigField.getFontSize()).orElse(6));
Rectangle rect = null;
FieldPosition fieldPosition = null;
//ADD EMPTY FIELD
if (StringUtils.isBlank(sigField.getName()) && box != null) {
fieldName = generateFieldName();
rect = new Rectangle(box.getLowerLeftX(), box.getLowerLeftY(), box.getLowerLeftX() + box.getWidth(),
box.getLowerLeftY() + box.getHeight());
appearance.setVisibleSignature(rect, pageNumber, fieldName);
////////////////////////////////// TRY TO ADD EXTRA SIGNATURE FIELD///////////////////////////////////////////
Rectangle documentRectangle = reader.getPageSize(pageNumber);
PdfStamper stamper = appearance.getStamper();
float pageMargin = 10;
float tableMargin = 15;
int numberOfFields = 1; // 1 sigField
float headerWidth = (documentRectangle.getWidth() - (pageMargin * 2));
// Table with signature field
PdfPTable table = new PdfPTable(1);
table.setTotalWidth(headerWidth - (tableMargin * 4));
table.setLockedWidth(Boolean.TRUE);
table.setWidthPercentage(100);
float posXTable = (pageMargin + (headerWidth - table.getTotalWidth()) / 2);
float posYTable = 400; // custom y position
int height = 70; // custom height
for (int i = 0; i < numberOfFields; i++) {
String sigFieldName = String.format(Constant.SIGNATURE_FIELD_PREFIX + "%s", (i + 1));
table.addCell(createSignatureFieldCell(stamper, sigFieldName, height, pageNumber));
}
table.writeSelectedRows(0, -1, posXTable, posYTable, stamper.getOverContent(pageNumber));
////////////////////////////////// END TRY TO ADD EXTRA SIGNATURE FIELD///////////////////////////////////////////
} else {
//APPLY SIGNATURE TO EXISTING EMPTY FIELD
List<FieldPosition> acroFields = reader.getAcroFields().getFieldPositions(sigField.getName());
fieldPosition = acroFields.get(0);
appearance.setVisibleSignature(fieldName);
}
// --------------------------- Custom signature appearance ---------------------
PdfTemplate t = appearance.getLayer(2);
Rectangle sigRect = null;
if (fieldPosition != null) {
sigRect = fieldPosition.position;
} else {
sigRect = new Rectangle(box.getLowerLeftX(), box.getLowerLeftY(), box.getLowerLeftX() + box.getWidth(),
box.getLowerLeftY() + box.getHeight());
}
// Left rectangle
Rectangle leftRect = new Rectangle(0, 0, (sigRect.getWidth() / 5), (sigRect.getHeight() / 2));
ColumnText ct1 = new ColumnText(t);
ct1.setSimpleColumn(leftRect);
Image im1 = Image.getInstance(icon.getAbsolutePath());
float ratio1 = leftRect.getHeight() / im1.getHeight();
im1.scaleToFit(im1.getWidth() * ratio1, im1.getHeight() * ratio1);
Paragraph p = createParagraph("Digital sign", font, Constant.PARAGRAPH_LEADING, Constant.MARGIN * 9);
ct1.addElement(new Chunk(im1, Constant.MARGIN * 10, 0));
ct1.addElement(p);
ct1.go();
// Middle rectangle
Rectangle middleRect = new Rectangle((sigRect.getWidth() / 5), 0,
(leftRect.getWidth() + sigRect.getWidth() / 5), (sigRect.getHeight() / 2));
ColumnText ct2 = new ColumnText(t);
ct2.setSimpleColumn(middleRect);
if (visibleSignatureImage != null) {
Image im2 = Image.getInstance(image.getAbsolutePath());
float ratio2 = sigRect.getHeight() / im2.getHeight();
im2.scaleToFit(im2.getWidth() * ratio2, im2.getHeight() * ratio2);
ct2.addElement(new Chunk(im2, 0, 0));
ct2.go();
}
// TextFields
List<TextField> textFields = fillSignatureFieldText(chain, sigProperties, font);
// Right rectangle - Names
Rectangle rightRectNames = new Rectangle(
(Constant.MARGIN * 5 + leftRect.getWidth() + middleRect.getWidth()), 0,
(leftRect.getWidth() + middleRect.getWidth() + sigRect.getWidth() / 4),
sigRect.getHeight() - Constant.MARGIN);
ColumnText ct31 = new ColumnText(t);
ct31.setSimpleColumn(rightRectNames);
List<Paragraph> paragraphsNames = textFields.stream()
.map(e -> createParagraph(e.getName(), font, Constant.PARAGRAPH_LEADING, 0))
.collect(Collectors.toList());
paragraphsNames.forEach(ct31::addElement);
ct31.go();
// Right rectangle - Values
Rectangle rightRectValues = new Rectangle(
(Constant.MARGIN * 4 + leftRect.getWidth() + middleRect.getWidth() + rightRectNames.getWidth()), 0,
sigRect.getWidth(), (sigRect.getHeight() - Constant.MARGIN));
ColumnText ct32 = new ColumnText(t);
ct32.setSimpleColumn(rightRectValues);
List<Paragraph> paragraphsValues = textFields.stream()
.map(e -> createParagraph(e.getValue(), font, Constant.PARAGRAPH_LEADING, 0))
.collect(Collectors.toList());
paragraphsValues.forEach(ct32::addElement);
ct32.go();
// --------------------------- Custom signature appearance ---------------------
}
return appearance;
}
//this is used to first create the empty fields
protected static PdfPCell createSignatureFieldCell(PdfWriter writer, String name, int height) {
PdfPCell cell = new PdfPCell();
cell.setMinimumHeight(height);
cell.setBackgroundColor(BaseColor.WHITE);
PdfFormField field = PdfFormField.createSignature(writer);
field.setFieldName(name);
field.setFlags(PdfAnnotation.FLAGS_PRINT);
cell.setCellEvent(new MySignatureFieldEvent(field, null, 0));
return cell;
}
//this is used to try to add the extra empty field to signed document
protected static PdfPCell createSignatureFieldCell(PdfStamper stamper, String name, int height, int pageNumber) {
PdfPCell cell = new PdfPCell();
cell.setMinimumHeight(height);
cell.setBackgroundColor(BaseColor.WHITE);
PdfFormField field = PdfFormField.createSignature(stamper.getWriter());
field.setFieldName(name);
field.setFlags(PdfAnnotation.FLAGS_PRINT);
cell.setCellEvent(new MySignatureFieldEvent(field, stamper, pageNumber));
return cell;
}
public static class MySignatureFieldEvent implements PdfPCellEvent {
public PdfFormField field;
public PdfStamper stamper;
public int pageField;
public MySignatureFieldEvent(PdfFormField field, PdfStamper stamper, int pageField) {
this.field = field;
this.stamper = stamper;
this.pageField = pageField;
}
public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
PdfWriter writer = canvases[0].getPdfWriter();
field.setPage();
field.setWidget(position, PdfAnnotation.HIGHLIGHT_INVERT);
if (stamper == null) {
writer.addAnnotation(field);
}else {
stamper.addAnnotation(field, pageField);
}
}
}
First of all, originally Adobe interpreted the certification levels as described in this answer. In particular, if a document has a certification signature, then adding new fields is forbidden, even signature fields.
This strictness appears to have been lost along the way but may again be applied any time after updates, in particular after the recently published certification attacks on pdf-insecurity.org exploited this relaxed option.
That been said, though, what you never are allowed to do is changing the static page content! In your code, though, you add the additional signature fields by adding a table (with events) to the document. This table will change the static page content.
Thus, try to only add a new signature field.

Java how change font in converter pdf - pdfbox

i have a problem. I create application JavaFX management for data base. I decided to convert data from tableview to pdf. For this I used a pdfbox. I can't change font in my converter pdf. How can do it? Because helvetica does not support the UTF-8 (ą, ę, ź ...).
enter code here public enum Orientation{
PORTRAIT, LANDSCAPE
};
public boolean doPrintToPdf(List<List> list, File saveLoc,Orientation orientation) {
try {
if (saveLoc == null) {
return false;
}
if (!saveLoc.getName().endsWith(".pdf")) {
saveLoc = new File(saveLoc.getAbsoluteFile() + ".pdf");
}
//Inicjalizacja dokumentu
PDDocument doc = new PDDocument();
PDPage page = new PDPage();
if (orientation == Orientation.LANDSCAPE) {
page.setMediaBox(new PDRectangle(PDRectangle.A4.getHeight(), PDRectangle.A4.getWidth()));
} else {
page.setMediaBox(new PDRectangle(PDRectangle.A4.getWidth(), PDRectangle.A4.getHeight()));
}
doc.addPage(page);
float margin = 10;
float tableWidth = page.getMediaBox().getWidth() - (2 * margin);
float yStartNewPage = page.getMediaBox().getHeight() - (2 * margin);
float yStart = yStartNewPage;
float bottomMargin = 0;
BaseTable dataTable = new BaseTable(yStart, yStartNewPage, bottomMargin, tableWidth, margin, doc, page, true,
true);
DataTable t = new DataTable(dataTable, page);
t.addListToTable(list, DataTable.HASHEADER);
dataTable.draw();
doc.save(saveLoc);
doc.close();
return true;
} catch (IOException e) {
DialogsUtils.errorDialog(e.getMessage());
}
return false;

Detecting text field overflow

Assuming I have a PDF document with a text field with some font and size defined, is there a way to determine if some text will fit inside the field rectangle using PDFBox?
I'm trying to avoid cases where text is not fully displayed inside the field, so in case the text overflows given the font and size, I would like to change the font size to Auto (0).
This code recreates the appearance stream to be sure that it exists so that there is a bbox (which can be a little bit smaller than the rectangle).
public static void main(String[] args) throws IOException
{
// file can be found at https://issues.apache.org/jira/browse/PDFBOX-142
// https://issues.apache.org/jira/secure/attachment/12742551/Testformular1.pdf
try (PDDocument doc = PDDocument.load(new File("Testformular1.pdf")))
{
PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
PDTextField field = (PDTextField) acroForm.getField("Name");
PDAnnotationWidget widget = field.getWidgets().get(0);
// force generation of appearance stream
field.setValue(field.getValue());
PDRectangle rectangle = widget.getRectangle();
PDAppearanceEntry ap = widget.getAppearance().getNormalAppearance();
PDAppearanceStream appearanceStream = ap.getAppearanceStream();
PDRectangle bbox = appearanceStream.getBBox();
float fieldWidth = Math.min(bbox.getWidth(), rectangle.getWidth());
String defaultAppearance = field.getDefaultAppearance();
System.out.println(defaultAppearance);
// Pattern must be improved, font may have numbers
// /Helv 12 Tf 0 g
final Pattern p = Pattern.compile("\\/([A-z]+) (\\d+).+");
Matcher m = p.matcher(defaultAppearance);
if (!m.find() || m.groupCount() != 2)
{
System.out.println("oh-oh");
System.exit(-1);
}
String fontName = m.group(1);
int fontSize = Integer.parseInt(m.group(2));
PDResources resources = appearanceStream.getResources();
if (resources == null)
{
resources = acroForm.getDefaultResources();
}
PDFont font = resources.getFont(COSName.getPDFName(fontName));
float stringWidth = font.getStringWidth("Tilman Hausherr Tilman Hausherr");
System.out.println("stringWidth: " + stringWidth * fontSize / 1000);
System.out.println("field width: " + fieldWidth);
}
}
The output is:
/Helv 12 Tf 0 g
stringWidth: 180.7207
field width: 169.29082

PDFBOX: Indexing using pdfbox

I am in requirement of creating an index for PDF document & based on the index i want to display the page.
problem is page number are created dynamically so static page number cannot be used, can anyone suggest me links or examples
here is my code and it works for me to redirect into different pages while clicking in the page number on index page
public class LinkPdf {
static final float INCH = 72;
public static List<PDAnnotation> annotations;
#SuppressWarnings("null")
public static void main(String[] args) throws Exception {
PDRectangle position = null;
PDDocument document = new PDDocument();
try {
for (int i = 0; i < 10; i++) {
PDPage page = new PDPage();
document.addPage(page);
}
PDPage page1 = document.getPage(0);
HashMap<Integer, String> pgs = new HashMap<Integer, String>();
for (int i = 0; i < document.getNumberOfPages(); i++) {
pgs.put(i, "Jump to Page" + i);
}
PDFont font = PDType1Font.HELVETICA_BOLD;
PDPageContentStream contents = new PDPageContentStream(document,
page1);
contents.beginText();
contents.setFont(font, 18);
contents.newLineAtOffset(50, 600);
contents.setLeading(20f);
contents.showText("PDFBox");
position = new PDRectangle();
for (int i = 0; i < document.getNumberOfPages(); i++) {
contents.newLine();
contents.showText(pgs.get(i));
contents.newLine();
}
contents.endText();
contents.close();
PDRectangle[] pos1 = new PDRectangle[document.getNumberOfPages()];
for(int i=0;i<document.getNumberOfPages();i++){
pos1[i]=new PDRectangle();
pos1[i].setLowerLeftX(50);
pos1[i].setLowerLeftY(575-(i*40));
pos1[i].setUpperRightX(INCH + 100);
pos1[i].setUpperRightY(585-(i*40));
getPage(document, page1, pgs.get(i), i, pos1[i]);
}
document.save("D:/link.pdf");
System.out.println("Completed");
} finally {
document.close();
}
}
public static void getPage(PDDocument document, PDPage page1, String txt,
int pageno, PDRectangle position) throws IOException {
annotations = page1.getAnnotations();
PDBorderStyleDictionary borderThick = new PDBorderStyleDictionary();
borderThick.setWidth(INCH / 12); // 12th inch
PDBorderStyleDictionary borderThin = new PDBorderStyleDictionary();
borderThin.setWidth(INCH / 72); // 1 point
PDBorderStyleDictionary borderULine = new PDBorderStyleDictionary();
borderULine.setStyle(PDBorderStyleDictionary.STYLE_UNDERLINE);
borderULine.setWidth(INCH / 72); // 1 point
float pw = page1.getMediaBox().getUpperRightX();
float ph = page1.getMediaBox().getUpperRightY();
float textWidth = PDType1Font.TIMES_BOLD.getStringWidth("PDFBox") / 1000 * 18;
PDAnnotationLink pageLink = new PDAnnotationLink();
pageLink.setBorderStyle(borderULine);
textWidth = PDType1Font.TIMES_BOLD.getStringWidth(txt) / 1000 * 18;
pageLink.setRectangle(position);
PDActionGoTo actionGoto = new PDActionGoTo();
PDPageDestination dest = new PDPageFitWidthDestination();
dest.setPage(document.getPage(pageno));
actionGoto.setDestination(dest);
pageLink.setAction(actionGoto);
annotations.add(pageLink);
}
}

Categories