I have used PDFBox version 2.0 to generated a PDF containing a clickable URL.
// Create a new annotation and make it invisible
PDAnnotationLink txtLink = new PDAnnotationLink();
txtLink.setInvisible(true);
// Add an action
PDActionURI action = new PDActionURI();
action.setURI(url);
txtLink.setAction(action);
// Create a new rectangle that will be the clickable area
PDRectangle position = new PDRectangle();
position.setLowerLeftX(currentXpos);
position.setLowerLeftY(currentYpos - rectangleHeight);
position.setUpperRightX(currentXpos + rectangleWidth);
position.setUpperRightY(currentYpos);
// Write the "Link" string in blue
contentStream.setNonStrokingColor(Color.blue);
contentStream.showText(elm.text());
contentStream.setNonStrokingColor(Color.black);
// Make the rectangle a clickable link and add it to the page
txtLink.setRectangle(position);
page.getAnnotations().add(txtLink);
When I click on the generated PDF in Chrome 45, the document is opened in the Chrome's PDF viewer. The link is clickable, no problem.
If I click on the generated PDF in Firefox (41.0.1) or IE 11, the document is loaded in the Adobe PDF viewer plugin and the link is not clickable. The mouse-over displays the correct URL, but nothing happens when I click the link.
Is this a security issue? Is there anything I can do in the PDFBox code to make the link clickable always?
I was able to hide the border by setting the width to 0:
// Create a new annotation and make it visible
PDAnnotationLink txtLink = new PDAnnotationLink();
txtLink.setInvisible(false);
// Set the border to zero to hide it
PDBorderStyleDictionary border = new PDBorderStyleDictionary();
border.setWidth(0);
txtLink.setBorderStyle(border);
Related
I am developing an Android app for flight reservation and i am using firebase Database for storing and retriving data. I need to generate a PDF of Ticket and contents should be changed as per passenger details and stored in local directory. I have a template of Ticket. What should i do?
Thank you in advance.
Since Android 5 you can use PdfDocument and its friend classes to generate a PDF document on Android device. The official documentation is here. There is no library to use a template with PdfDocument. You have to use some drawing primitive to accomplish your task.
Here is a sample to generate a PDF with a single page A4:
// create a new document
PdfDocument document = new PdfDocument();
// crate a page description
PageInfo pageInfo = new PageInfo.Builder(595, 842, 1).create();
// start a page
Page page = document.startPage(pageInfo);
Canvas canvas=page.getCanvas());
// draw something on the page
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawCircle(50, 50, 30, paint);
// finish the page
document.finishPage(page);
// write the document content
document.writeTo(getOutputStream());
// close the document
document.close();
The page content is defined with Canvas object. Just another example. I hope this helps you.
In Xamarin.Forms, I want to convert my xaml page UI (sometimes my page is scrollable when having more content) into the PDF. I have tried the PDFSharp (https://github.com/akgulebubekir/PDFSharp.Xamarin.Forms) open source. But it works only on UWP and having some issues in iOS and Android.
So is there any free open source plugin available to convert XAML UI into PDF in all three platforms? If open source not available, is there any other way or work around to achieve it in android, ios & UWP?
Thanks in advance.
I had a bit of trouble with this and managed to do it using UIkit and PdfKit tools.
Here is an exemple:
using UIKit;
using PdfKit;
//Calculate scroll View height
double xamlHeight = XamlFullPage.Height;
int numberOfPages = (int)Math.Ceiling(xamlHeight / Application.Current.MainPage.Height);
// Create a new PDF document
PdfDocument document = new PdfDocument();
for (int i = 0; i<numberOfPages; i++) //while the all the page have not been taken into account
{
await SummaryScrollView.ScrollToAsync(0, i*Application.Current.MainPage.Height, false).ConfigureAwait(false); //find the beginnig of the current page
//Captures the XAML page as image and returns the image in memory stream
var image = UIScreen.MainScreen.Capture();
// Create a page with the printscreen
PdfPage page = new PdfPage(image);
//insert page in the i position
document.InsertPage(page, i);
page.Dispose();
}
//Write file in temp foleder
document.Write(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "TuitionFees" + fileName + ".pdf"));`
I'm writing some javascript for a Windows 8 app. I'm trying to render a drawing to a canvas element that is a child of a dynamically created document.
I've got this function returning a new document:
initPrintDoc: function () {
var emptyDoc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null),
emptyBody = document.createElement('body'),
emptyCanvas = document.createElement('canvas'),
debugDiv = document.createElement('div'),
debugMsg = document.createTextNode("[PRINT] : This is a test print source.");
//Initialize attributes for elements
emptyBody.setAttribute('id', 'pdf-container');
emptyCanvas.setAttribute('id', 'render-output');
debugDiv.setAttribute('id', 'debug-output');
debugDiv.appendChild(debugMsg);
emptyBody.appendChild(debugDiv);
emptyBody.appendChild(emptyCanvas);
emptyDoc.documentElement.appendChild(emptyBody);
return emptyDoc;
},
The returned document object is not the document object that is displayed in the Windows 8 App UI at runtime. I am using this dynamically created document as the parameter for the MSApp.getHtmlPrintDocumentSource(). Unfortunately, no matter what I do to the canvas element that is inside this document, the canvas never shows a rendering in the actual printout, nor in the simple preview window found in the charms bar after clicking a selected printer.
My question is: does a canvas element require its container document to be displayed in the browser window? Can you manipulate a canvas element in a dynamically created document, and expect those manipulations to show when you display that document?
I'm working to refactor a PDF form web application that is using the Active PDF Toolkit and the FDFToolkit from Adobe. My goal is to use iTextSharp to:
Pre-populate the form fields with data from the database
Allow the user to attach a signature and/or barcode image via FDF
Item #1 is not the problem. Item #2 is the biggest challenge. Let me provide some background:
This is a web application which renders the PDF form once. After the initial load, there are 2 key buttons on the form which submit the PDF form to a URL with an action parameter in the query string. These buttons are called "Save" and "Sign". The Save button takes the FDF field dictionary and saves it to the database. The Sign button looks up the signature for the logged-in user and attaches the signature image to the FDF and writes the FDF to the HTTP Response.
The FDFToolkit supports attaching an image to a field using this method:
FDFSetAP(string bstrFieldName, short whichFace, string bstrFileName, short pageNum)
iTextSharp does not offer a comparable method in the FdfWriter class. I've considered subclassing the FdfWriter class and adding my own method to attach an image, but wanted to reach out here to see if anyone has had the same problem.
I have been able to overlay an image on top of a field using this method, but this is in the underlying PDF and not the FDF.
AcroFields.FieldPosition pos = _Stamper.AcroFields.GetFieldPositions("SIGNATUREFIELD").First();
Image signature = Image.GetInstance("Signature.gif");
image.SetAbsolutePosition(pos.position.Left, pos.position.Bottom);
image.ScaleToFit(pos.position.Width, pos.position.Height);
PdfContentByte pcb = _Stamper.GetOverContent(pos.page);
pcb.AddImage(image);
Thanks!
I've put images on forms by using the PdfStamper and making Pushbutton fields. You can replace your existing field with a Pushbutton field and set the Pushbutton to READ_ONLY so that it can't be pressed and it will look like a static image. This will keep the image you're trying to add as a field annotation instead of adding it to the page content.
using (PdfStamper stamper = new PdfStamper(new PdfReader(inputFile), File.Create(outputFile)))
{
AcroFields.FieldPosition fieldPosition = stamper.AcroFields.GetFieldPositions(fieldName)[0];
PushbuttonField imageField = new PushbuttonField(stamper.Writer, fieldPosition.position, fieldName);
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.Image = iTextSharp.text.Image.GetInstance(imageFile);
imageField.ScaleIcon = PushbuttonField.SCALE_ICON_ALWAYS;
imageField.ProportionalIcon = false;
imageField.Options = BaseField.READ_ONLY;
stamper.AcroFields.RemoveField(fieldName);
stamper.AddAnnotation(imageField.Field, fieldPosition.page);
}
I pieced together some code to insert a dynamic image into a PDF using both ColdFusion and iText, while filling in some form fields as well. After I got it working and blogged about it, I couldn't help but think that there might be a better way to accomplish this. I'm using the basic idea of this in a production app right now so any comments or suggestion would be most welcomed.
<cfscript>
// full path to PDF you want to add image to
readPDF = expandpath(”your.pdf”);
// full path to the PDF we will output. Using creatUUID() to create
// a unique file name so we can delete it afterwards
writePDF = expandpath(”#createUUID()#.pdf”);
// full path to the image you want to add
yourimage = expandpath(”dynamic_image.jpg”);
// JAVA STUFF!!!
// output buffer to write PDF
fileIO = createObject(”java”,”java.io.FileOutputStream”).init(writePDF);
// reader to read our PDF
reader = createObject(”java”,”com.lowagie.text.pdf.PdfReader”).init(readPDF);
// stamper so we can modify our existing PDF
stamper = createObject(”java”,”com.lowagie.text.pdf.PdfStamper”).init(reader, fileIO);
// get the content of our existing PDF
content = stamper.getOverContent(reader.getNumberOfPages());
// create an image object so we can add our dynamic image to our PDF
image = createobject(”java”, “com.lowagie.text.Image”);
// get the form fields
pdfForm = stamper.getAcroFields();
// setting a value to our form field
pdfForm.setField(”our_field”, “whatever you want to put here”);
// initalize our image
img = image.getInstance(yourimage);
// centering our image top center of our existing PDF with a little margin from the top
x = (reader.getPageSize(1).width() - img.scaledWidth()) - 50;
y = (reader.getPageSize(1).height() - img.scaledHeight()) / 2 ;
// now we assign the position to our image
img.setAbsolutePosition(javacast(”float”, y),javacast(”float”, x));
// add our image to the existing PDF
content.addImage(img);
// flattern our form so our values show
stamper.setFormFlattening(true);
// close the stamper and output our new PDF
stamper.close();
// close the reader
reader.close();
</cfscript>
<!— write out new PDF to the browser —>
<cfcontent type=”application/pdf” file = “#writePDF#” deleteFile = “yes”>
<cfpdf> + DDX seems possible.
See http://forums.adobe.com/thread/332697
I have made it in another way with itext library
I don´t want overwrite my existing pdf with the image to insert, so just modify the original pdf inserting the image, just insert with itext doesn´t work for me.
So, I have to insert the image into a blank pdf (http://itextpdf.com/examples/iia.php?id=59)
And then join my original pdf and the new pdf-image. Obtaining one pdf with several pages.
(http://itextpdf.com/examples/iia.php?id=110)
After that you can overlay the pdf pages with this cool concept
http://itextpdf.com/examples/iia.php?id=113