appendDocument method of PDFBox not working - pdfbox

Following is the chunk of my code:
PDFMergerUtility mergePdf = new PDFMergerUtility();
File f1 = new File("D:/out/pdf-sample.pdf");
File f2 = new File("D:/out/Combined.pdf");
PDDocument pd1 = PDDocument.load(f1);
PDDocument pd2 = PDDocument.load(f2);
mergePdf.appendDocument(pd1, pd2);
There is no error on the console; but the content isn't just getting appended.

pd2.close();
pd1.save(m_Dest);
pd1.close();

Related

allow arabic text in pdf table using itext7 (xamarin android)

I have to put my list data in a table in a pdf file. My data has some Arabic words. When my pdf is generated, the Arabic words don't appear. I searched and found that I need itext7.pdfcalligraph so I installed it in my app. I found this code too https://itextpdf.com/en/blog/technical-notes/displaying-text-different-languages-single-pdf-document and tried to do something similar to allow Arabic words in my table but I couldn't figure it out.
This is a trial code before I apply it to my real list:
var path2 = global::Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
filePath = System.IO.Path.Combine(path2.ToString(), "myfile2.pdf");
stream = new FileStream(filePath, FileMode.Create);
PdfWriter writer = new PdfWriter(stream);
PdfDocument pdf2 = new iText.Kernel.Pdf.PdfDocument(writer);
Document document = new Document(pdf2, PageSize.A4);
FontSet set = new FontSet();
set.AddFont("ARIAL.TTF");
document.SetFontProvider(new FontProvider(set));
document.SetProperty(Property.FONT, "Arial");
string[] sources = new string[] { "يوم","شهر 2020" };
iText.Layout.Element.Table table = new iText.Layout.Element.Table(2, false);
foreach (string source in sources)
{
Paragraph paragraph = new Paragraph();
Bidi bidi = new Bidi(source, Bidi.DirectionDefaultLeftToRight);
if (bidi.BaseLevel != 0)
{
paragraph.SetTextAlignment(iText.Layout.Properties.TextAlignment.RIGHT);
}
paragraph.Add(source);
table.AddCell(new Cell(1, 1).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(paragraph));
}
document.Add(table);
document.Close();
I updated my code and added the arial.ttf to my assets folder . i'm getting the following exception:
System.InvalidOperationException: 'FontProvider and FontSet are empty. Cannot resolve font family name (see ElementPropertyContainer#setFontFamily) without initialized FontProvider (see RootElement#setFontProvider).'
and I still can't figure it out. any ideas?
thanks in advance
- C #
I have a similar situation for Turkish characters, and I've followed these
steps :
Create a folder under projects root folder which is : /wwwroot/Fonts
Add OpenSans-Regular.ttf under the Fonts folder
Path for font is => ../wwwroot/Fonts/OpenSans-Regular.ttf
Create font like below :
public static PdfFont CreateOpenSansRegularFont()
{
var path = "{Your absolute path for FONT}";
return PdfFontFactory.CreateFont(path, PdfEncodings.IDENTITY_H, true);
}
and use it like :
paragraph.Add(source)
.SetFont(FontFactory.CreateOpenSansRegularFont()); //set font in here
table.AddCell(new Cell(1, 1)
.SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER)
.Add(paragraph));
This is how I used font factory for Turkish characters ex: "ü,i,ç,ş,ö"
For Xamarin-Android, you could try
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var path = Path.Combine(documentsPath, "Fonts/Arial.ttf");
Look i fixed it in java,this may help you:
String font = "your Arabic font";
//the magic is in the next 4 lines:
PdfFontFactory.register(font);
FontProgram fontProgram = FontProgramFactory.createFont(font, true);
PdfFont f = PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H);
LanguageProcessor languageProcessor = new ArabicLigaturizer();
//and look here how i used setBaseDirection and don't use TextAlignment ,it will work without it
com.itextpdf.kernel.pdf.PdfDocument tempPdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(new PdfReader(pdfFile.getPath()), TempWriter);
com.itextpdf.layout.Document TempDoc = new com.itextpdf.layout.Document(tempPdfDoc);
com.itextpdf.layout.element.Paragraph paragraph0 = new com.itextpdf.layout.element.Paragraph(languageProcessor.process("الاستماره الالكترونية--الاستماره الالكترونية--الاستماره الالكترونية--الاستماره الالكترونية"))
.setFont(f).setBaseDirection(BaseDirection.RIGHT_TO_LEFT)
.setFontSize(15);

Adding external pdf content generated from SVG using apache batik to Source PDF using Itext with header and footer

I have the below requirement.
Convert the SVG to PDF using Apache batik
Prepare source PDF document with Header and Footer using IText 7
Take the converted PDF and embed it in the content of the source PDF
I have seen IText supports converting an SVG to Image but the output is not proper. The output from batik seems to be perfect.
Below is my code. Can anyone please suggest a proper approach ? I am not able to achieve it
SVG to PDF using batik
FileInputStream inputStream = new FileInputStream(new File(Paths.get("Input").toAbsolutePath()+"/test.svg"));
byte[] bytes = IOUtils.toByteArray(inputStream);
FileOutputStream pdfOutputStream = new FileOutputStream(new File(Paths.get("Output").toAbsolutePath()+"/convertedSvg.pdf"));
Transcoder transcoder = new PDFTranscoder();
TranscoderInput transcoderInput = new TranscoderInput(new ByteArrayInputStream(bytes));
TranscoderOutput transcoderOutput = new TranscoderOutput(pdfOutputStream);
int dpi = 300;
transcoder.addTranscodingHint(PDFTranscoder.KEY_WIDTH, new Float(dpi * 29.7));
transcoder.addTranscodingHint(PDFTranscoder.KEY_HEIGHT, new Float(dpi * 42.0));
transcoder.addTranscodingHint(PDFTranscoder.KEY_PIXEL_UNIT_TO_MILLIMETER,(25.4f / 72f));
transcoder.transcode(transcoderInput, transcoderOutput);
iText Code
PdfWriter writer = new PdfWriter(new FileOutputStream(new File(Paths.get("Output").toAbsolutePath()+"/final.pdf")));
PdfDocument pdfDoc = new PdfDocument(writer);
pdfDoc.setDefaultPageSize(PageSize.A3.rotate());
NormalPageHeader headerHandler = new NormalPageHeader(Paths.get("images").toAbsolutePath() + "\\logo.png", pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
PageEndEvent pageEndEvent = new PageEndEvent(Paths.get("images").toAbsolutePath() + "\\FooterLineExternal.png" ,pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, pageEndEvent);
Document doc = new Document(pdfDoc);
doc.getPageEffectiveArea(PageSize.A3.rotate());
Table imageTable = new Table(1);
imageTable.setBorder(Border.NO_BORDER);
imageTable.setWidth(UnitValue.createPercentValue(100));
Cell cell = new Cell();
Paragraph paragraph = new Paragraph("Horizontal Trajectory");
paragraph.setVerticalAlignment(VerticalAlignment.TOP);
cell.add(paragraph);
cell.setBorder(Border.NO_BORDER);
cell.setPaddingTop(50);
imageTable.addCell(cell);
doc.add(imageTable);
doc.close();

Docusign duplicated Signature tags on all pages

I am using Docusign to add a signature my PDF documents in c#.
I have some html file, I add to end of html div with text "SignHere" that Docusign will recognize the zone for signature, but the problem that after converting html to pdf and send Docusign, I see that "SignHere" option in all pages, not the last one.
What I am wrong wrong here?
My code, after converting html to pdf file:
if (System.IO.File.Exists(PdfPath))
{
byte[] fileBytes = System.IO.File.ReadAllBytes(PdfPath);
EnvelopeDefinition envDef = new EnvelopeDefinition();
envDef.EmailSubject = envDefEmailSubject;
envDef.EventNotification = new EventNotification();
envDef.EventNotification.Url = envDefEventNotificationUrl;
envDef.EventNotification.LoggingEnabled = "true";
envDef.EventNotification.IncludeDocuments = "true";
envDef.EventNotification.RequireAcknowledgment = "true";
envDef.EventNotification.IncludeCertificateWithSoap = "false";
envDef.EventNotification.RequireAcknowledgment = "true";
envDef.EventNotification.UseSoapInterface = "false";
envDef.EventNotification.EnvelopeEvents = new List<EnvelopeEvent>();
EnvelopeEvent envelopeEventSent = new EnvelopeEvent();
envelopeEventSent.EnvelopeEventStatusCode = "sent";
envDef.EventNotification.EnvelopeEvents.Add(envelopeEventSent);
EnvelopeEvent envelopeEventDelivered = new EnvelopeEvent();
envelopeEventDelivered.EnvelopeEventStatusCode = "delivered";
envDef.EventNotification.EnvelopeEvents.Add(envelopeEventDelivered);
EnvelopeEvent envelopeEventSentCompleted = new EnvelopeEvent();
envelopeEventSentCompleted.EnvelopeEventStatusCode = "completed";
envDef.EventNotification.EnvelopeEvents.Add(envelopeEventSentCompleted);
Document doc = new Document();
doc.DocumentBase64 = System.Convert.ToBase64String(fileBytes);
doc.Name = docName;
doc.DocumentId = docDocumentId;
envDef.Documents = new List<Document>();
envDef.Documents.Add(doc);
Signer signer = new Signer();
signer.Email = Email;
signer.Name = signerName + LeadName;
signer.RecipientId = signerRecipientId;
signer.Tabs = new Tabs();
//Custom Field For LeadId and PdfName
envDef.CustomFields = new CustomFields();
envDef.CustomFields.TextCustomFields = new List<TextCustomField>();
TextCustomField textCustomFieldLeadId = new TextCustomField();
textCustomFieldLeadId.Name = "LeadId";
textCustomFieldLeadId.Value = LeadId;
textCustomFieldLeadId.Required = "false";
textCustomFieldLeadId.Name = "false";
envDef.CustomFields.TextCustomFields.Add(textCustomFieldLeadId);
TextCustomField textCustomFieldSignedPdfName = new TextCustomField();
textCustomFieldSignedPdfName.Name = "SignedPdfName";
textCustomFieldSignedPdfName.Value = SignedPdfName;
textCustomFieldSignedPdfName.Required = "false";
textCustomFieldSignedPdfName.Name = "false";
envDef.CustomFields.TextCustomFields.Add(textCustomFieldSignedPdfName);
if (SignHereExist)
{
signer.Tabs.SignHereTabs = new List<SignHere>();
SignHere signHere = new SignHere();
signHere.RecipientId = signHereRecipientId;
signHere.AnchorXOffset = signHereAnchorXOffset;
signHere.AnchorYOffset = signHereAnchorYOffset;
signHere.AnchorIgnoreIfNotPresent = signHereAnchorIgnoreIfNotPresent;
signHere.AnchorUnits = "inches";
signHere.AnchorString = signHereAnchorString;
signer.Tabs.SignHereTabs.Add(signHere);
envDef.Recipients = new Recipients();
envDef.Recipients.Signers = new List<Signer>();
envDef.Recipients.Signers.Add(signer);
envDef.Status = "sent";
ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");
DocuSign.eSign.Client.Configuration cfi = new DocuSign.eSign.Client.Configuration(apiClient);
string authHeader = "{\"Username\":\"" + x+ "\", \"Password\":\"" + x+ "\", \"IntegratorKey\":\"" + x+ "\"}";
cfi.AddDefaultHeader("X-DocuSign-Authentication", authHeader);
EnvelopesApi envelopesApi = new EnvelopesApi(cfi);
EnvelopeSummary envelopeSummary = envelopesApi.CreateEnvelope(accountID, envDef);
}
You are using Docusign Auto-Place (Anchor Tagging) in your request.
signHere.AnchorString = signHereAnchorString;
This will trigger a scan on the text in the document. If the scan finds the text specified in the variable signHereAnchorString anywhere in the document, it automatically places the "SignHere" option next to the text. That is the reason you are seeing "SignHere" option on all pages
You have couple of options if you want to place the Tag only on the last page
Option 1 - Using Anchor Tags: (See documentation here)
Modify your document to contain a unique string where you want to place the Signature tag. In this case, you could add the text "SignHereLastPage" in white font color (so that it isn't visible in the document) to where you want to place the Signature tag on the Document. Use "SignHereLastPage" as the anchor string.
You will just need to change one line in your code
signHere.AnchorString = "SignHereLastPage";
Option 2 - Fixed (or Absolute) Positioning (See documentation here)
You can use Absolute position of Tags and specify where you want to place the signature Tag. See Api recipe here
signer.Tabs.SignHereTabs = new List<SignHere>();
SignHere signHere = new SignHere();
signHere.DocumentId =docDocumentId;
signHere.PageNumber = "1"; // Specify the last Page number here.
signHere.RecipientId = signHereRecipientId;
signHere.XPosition = "100"; //You can adjust this based on your document
signHere.YPosition = "100"; //You can adjust this based on your document
signer.Tabs.SignHereTabs.Add(signHere);

alfresco - convert docx to pdf and create a new version

I' m trying to convert a docx document to pdf and store the newly created pdf file as a new version.
This is the test code:
var document = search.findNode("workspace://SpacesStore/30f334f3-d357-4ea6-a09f-09eab2da7488");
var folder = document.parent
var pdf = document.transformDocument('application/pdf');
pdf.name = "tranformed-" + pdf.name;
pdf.save();
document.name = "new-" + document.name + ".pdf";
document.mimetype = "application/pdf";
document.content = pdf.content;
document.save();
The document ends up empty.
Is this type of conversion possible with javaScript?
This Code create new pdf from docx and created pdf stored as version 1.0
var document = search.findNode("workspace://SpacesStore/30f334f3-d357-4ea6-a09f-09eab2da7488");
var folder = document.parent
var pdf = document.transformDocument('application/pdf');
pdf.name = "tranformed-" + pdf.name;
pdf.save();
Thanks for your support.
The problem was assigning the pdf content.
The following code seems to work only with plain text content:
document.content = pdf.content;
Paradoxically, the following is needed when assigning pdf content to a document.
document.properties.content.write(pdf.properties.content);
Thanks.

Attachments not showing up in pdf document - created using pdfbox

I m trying to attach an swf file to a pdf document. Below is my code (excerpted from the pdfbox-examples). while i can see that the file is attached based on the size of the file - with & without the attachment, I can't see / locate it in the pdf document. I do see textual content correctly displayed. Can someone tell me what I m doing wrong & help me fix the issue?
doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage( page );
PDFont font = PDType1Font.HELVETICA_BOLD;
String inputFileName = "sample.swf";
InputStream fileInputStream = new FileInputStream(new File(inputFileName));
PDEmbeddedFile ef = new PDEmbeddedFile(doc, fileInputStream );
PDPageContentStream contentStream = new PDPageContentStream(doc, page,true,true);
//embedded files are stored in a named tree
PDEmbeddedFilesNameTreeNode efTree = new PDEmbeddedFilesNameTreeNode();
//first create the file specification, which holds the embedded file
PDComplexFileSpecification fs = new PDComplexFileSpecification();
fs.setEmbeddedFile(ef);
//now lets some of the optional parameters
ef.setSubtype( "swf" );
ef.setCreationDate( new GregorianCalendar() );
//now add the entry to the embedded file tree and set in the document.
Map<String, COSObjectable> efMap = new HashMap<String, COSObjectable>();
efMap.put("My first attachment", fs );
efTree.setNames( efMap );
//attachments are stored as part of the "names" dictionary in the document catalog
PDDocumentNameDictionary names = new PDDocumentNameDictionary( doc.getDocumentCatalog() );
names.setEmbeddedFiles( efTree );
doc.getDocumentCatalog().setNames( names );
After struggling with the same thing, I've discovered this is a known issue. Attachments haven't worked for a while I guess.
Here's a link to the issue on the apache forum.
There is a hack suggested here that you can use.
I tried it and it worked!
the other work around i found is after you call setNames on your PDEmbeddedFilesNameTreeNode remove the limits: ((COSDictionary
)efTree.getCOSObject()).removeItem(COSName.LIMITS); ugly hack, but it
works, without having to recompile pdfbox
Attachment works fine with new version of PDFBox 2.0,
public static boolean addAtachement(final String fileName, final String... attachements) {
if (Objects.isNull(fileName)) {
throw new NullPointerException("fileName shouldn't be null");
}
if (Objects.isNull(attachements)) {
throw new NullPointerException("attachements shouldn't be null");
}
Map<String, PDComplexFileSpecification> efMap = new HashMap<String, PDComplexFileSpecification>();
/*
* Load PDF Document.
*/
try (PDDocument doc = PDDocument.load(new File(fileName))) {
/*
* Attachments are stored as part of the "names" dictionary in the
* document catalog
*/
PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
/*
* First we need to get all the existed attachments, after that we
* can add new attachments
*/
PDEmbeddedFilesNameTreeNode efTree = names.getEmbeddedFiles();
if (Objects.isNull(efTree)) {
efTree = new PDEmbeddedFilesNameTreeNode();
}
Map<String, PDComplexFileSpecification> existedNames = efTree.getNames();
if (existedNames == null || existedNames.isEmpty()) {
existedNames = new HashMap<String, PDComplexFileSpecification>();
}
for (String attachement : attachements) {
/*
* Create the file specification, which holds the embedded file
*/
PDComplexFileSpecification fs = new PDComplexFileSpecification();
fs.setFile(attachement);
try (InputStream is = new FileInputStream(attachement)) {
/*
* This represents an embedded file in a file specification
*/
PDEmbeddedFile ef = new PDEmbeddedFile(doc, is);
/* Set some relevant properties of embedded file */
ef.setCreationDate(new GregorianCalendar());
fs.setEmbeddedFile(ef);
/*
* now add the entry to the embedded file tree and set in
* the document.
*/
efMap.put(attachement, fs);
}
}
efTree.setNames(efMap);
names.setEmbeddedFiles(efTree);
doc.getDocumentCatalog().setNames(names);
doc.save(fileName);
return true;
} catch (IOException e) {
System.out.println(e.getMessage());
return false;
}
}
To 'locate' or see an attached file in the PDF, you can't flip through its pages to find any trace of it there (like, an annotation).
In Acrobat Reader 9.x for example, you have to click on the "View Attachments" icon (looking like a paper-clip) on the left sidebar.