Replace a page in a PDF with iText7 - vb.net

I am in the process of updating some PDF editing tools from iTextSharp to iText7.
In iTextSharp there was a method in the pdfStamper class: pdfStamper.ReplacePage().
However, the pdfStamper class has been removed in iText7 and I am having trouble replicating the same functionality.
Say I have document X that needs page 4 replaced with page 1 of document Y but I want the result to be save to a new document Z.
So far I have 3 lines that use the CopyPageTo method. However any PDF document that gets created is only 1kb in size and corrupted.
Anyone have experience with the newer iText7 and the CopyPageTo method?
NewPagesReader = New PdfReader(strNewPageDocPath)
docNewPages = New PdfDocument(NewPagesReader)
OriginalDocReader = New PdfReader(strOrigPageDocPath)
docOringal = New PdfDocument(OriginalDocReader)
Dim docNew As PdfDocument
Dim NewPDFWriter As New PdfWriter(saver.FileName)
docNew = New PdfDocument(NewPDFWriter)
docOringal.CopyPagesTo(1, 3, docNew)
docNewPages.CopyPagesTo(1, 1, docNew)
docOringal.CopyPagesTo(5, 6, docNew)
ToWriter.Close()
docNew.Close()

Your code looks fine. Instead of copying all the pages to a new document, you can also delete and insert a page:
NewPagesReader = New PdfReader(strNewPageDocPath)
docNewPages = New PdfDocument(NewPagesReader)
OriginalDocReader = New PdfReader(strOrigPageDocPath)
Dim NewPDFWriter As New PdfWriter(saver.FileName)
docOringal = New PdfDocument(OriginalDocReader, NewPDFWriter)
docOringal.RemovePage(4)
docNewPages.CopyPagesTo(1, 1, docOringal, 4)
docOringal.Close()

Related

Generate PDF from gsp page

I am using grails 2.5.2.
I have created a table which shows all the data from database to gsp page and now i need to save that shown data in a pdf format with a button click.What will be the best way to show them into a PDF and save it to my directory. please Help
You can use itext for converting HTML into pdf using the code below:
public void createPdf(HttpServletResponse response, String args, String css, String pdfTitle) {
response.setContentType("application/force-download")
response.setHeader("Content-Disposition", "attachment;filename=${pdfTitle}.pdf")
Document document = new Document()
Rectangle one = new Rectangle(900, 600)
document.setPageSize(one)
PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream())
document.open()
ByteArrayInputStream bis = new ByteArrayInputStream(args.toString().getBytes())
ByteArrayInputStream cis = new ByteArrayInputStream(css.toString().getBytes())
XMLWorkerHelper.getInstance().parseXHtml(writer, document, bis, cis)
document.close()
}
Though answering this question late,take a look at grails export plugin.It will be useful if you want to export your data to excel and pdf( useful only if there is no in pre-defined template to export).
Got idea from itext. Used itext 2.1.7 and posted all the values to pdf from a controller method. Used images as background and paragraph and phrase to show values from database.

huge data export in pdf itextsharp

I try to export data in PDF there is huge data so when i export ..here i dont export data from gridview but actually here i create dummy gridview in code and bind data in that grid.. i am not displaying the data the grid in page .. I try below code
Private Sub ExportGridToPDF()
Using myMemoryStream As New MemoryStream()
Dim myDocument As New iTextSharp.text.Document(iTextSharp.text.PageSize.A1, 10.0F, 10.0F, 10.0F, 0.0F)
' Dim myDocument As New iTextSharp.text.Document()
Dim myPDFWriter As PdfWriter = PdfWriter.GetInstance(myDocument, myMemoryStream)
myDocument.Open()
' Add to content to your PDF here...
Dim sw As New StringWriter()
Dim hw As New HtmlTextWriter(sw)
GridView1.AllowPaging = False
GridView1.DataBind()
GridView1.RenderControl(hw)
' We're done adding stuff to our PDF.
myDocument.Add(hw)
myDocument.Close()
Dim content As Byte() = myMemoryStream.ToArray()
' Write out PDF from memory stream.
Using fs As FileStream = File.Create("eport_PDF.pdf")
fs.Write(content, 0, CInt(content.Length))
End Using
End Using
End Sub
when i run this shows an error
System.InvalidCastException: Unable to cast object of type 'System.Web.UI.HtmlTextWriter' to type 'iTextSharp.text.IElement'.
on this line
myDocument.Add(hw)
I use memory stream because of huge data when i use code without memory stream then shows an error Out of Memory exception so i use memory stream and now this shows different error
The Add() method in the Document object only accepts parameters that implement the IElement interface. You are passing an HtmlTextWriter object. That object is totally unrelated to iText. It is truly amazing that you would think this could work.
In this question, as in previous questions you posted (some of which are deleted), you refer to HTML. You were using HTMLWorker in Add image using itextsharp and the deleted question Out Of Memory Exception error itext sharp.
If you want to convert HTML to PDF, you should upgrade to iText 7 and use the pdfHTML add-on. Take a look at the tutorial to see how HTML to PDF conversion is done: https://developers.itextpdf.com/content/itext-7-converting-html-pdf-pdfhtml
In a comment to this answer however, you write: I'm not exporting data in HTML to PDF. OK, if that's true, then why do you refer to HTML in your code? That's very confusing.
Furthermore, you write I create dummy grid-view in code and bind data in it. Unfortunately, you don't give us any information about the format of that dummy grid-view. I assume, it's something you "invented" yourself, but if that's the case, how do you suppose that iText can magically understand the dummy grid-view you invented?
I started this answer by saying the the Add() method only accepts objects that implement the IElement interface. Since you are talking about a grid, it's probably interesting to use an iText table element. In iText 5, there's an object named PdfPTable; in iText 7, that object is simply named Table.
Many people with large data sets, create such a table object first, then add it to a Document. That's not always wise, because objects keep building up in memory, eventually resulting in an OutOfMemoryException. For large data sets, you should mark the table as a large element, and add the table gradually.
In iText 5, the code would look like this:
Document document = new Document();
FileStream stream = new FileStream(fileName, FileMode.Create);
var pdfWriter = PdfWriter.GetInstance(document, stream);
document.Open();
PdfPTable table = new PdfPTable(4);
table.Complete = false;
for (int i = 0; i < 1000000; i++) {
PdfPCell cell = new PdfPCell(new Phrase(i.ToString()));
table.AddCell(cell);
if (i > 0 && i % 1000 == 0) {
document.Add(table);
}
}
table.Complete = true;
document.Add(table);
document.Close();
We're adding 1000000 cells to a table with 4 columns, but we add the table every 1000 cells (so every 250 rows). This means that the content is flushed from memory on a regular basis, thus avoiding an OutOfMemoryException.
Since you seem to be new at iText, do yourself a favor, and upgrade to using iText 7. iText 5 is in maintenance mode, which means that no new functionality will be added to that version. For instance: if at some point someone asks you to produce PDF 2.0 files (the PDF 2.0 spec was released a couple of months ago), you will have to throw all your iText 5 code away, and start anew, because only iText 7 will support PDF 2.0.
The large table functionality in iText 7, is discussed at the end of chapter 5 of the tutorial:
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
Table table = new Table(new[] {1f, 1f, 1f}, true);
table.AddHeaderCell("Table header 1");
table.AddHeaderCell("Table header 2");
table.AddHeaderCell("Table header 3");
table.AddFooterCell("Table footer 1");
table.AddFooterCell("Table footer 2");
table.AddFooterCell("Table footer 3");
document.Add(table);
for (int i = 0; i < 1000; i++)
{
table.AddCell($"Row {i + 1}; column 1");
table.AddCell($"Row {i + 1}; column 2");
table.AddCell($"Row {i + 1}; column 3");
if (i % 50 == 0)
{
table.Flush();
}
}
table.Complete();
document.Close();
As you can see, the iText 7 code is much more intuitive. We create a table with 3 columns, and the second parameter (true) indicates that we will add a very large table. We add a header, we add a footer, and we add the table to the document. Then we add 1000 rows, but we Flush() the table every 50 rows. Flushing free memory, avoiding going out of memory. Once we're done, we Complete() the table.
All of this is documented on the official web site! There is no need for you to invent your own grid view. As you have found out, inventing your own grid view cannot possibly work.
Also important: you say iTextSharp, I say iText. We both mean the same thing: the PDF library produced by iText Group that can be used to create PDF documents from C# code. Only you are using the old name, whereas we try to avoid that name based on the advice of a Trademark who told us that there's a company named Sharp that doesn't appreciate other companies using the word Sharp in the context of brands that aren't related to their company. So please stop saying that you're using iTextSharp; you're using iText!

Losing javascript which is added into pdf using itext

I am trying to add javascript into a pdf using itext and later merge it with another pdf.
But the final merged pdf does not contain the javascript. The javascript is working fine if the pdf is not merged with another pdf.
Merging code :
FileOutputStream sectionR = new FileOutputStream(RESULT);
PdfCopyFields copier = new PdfCopyFields(sectionR);
for (String curInPath : listFile) {
PdfReader reader = new PdfReader(curInPath);
copier.addDocument(reader);
}
copier.close();
I tried to add JS to the resulting merged pdf, but it is not taking it. I guess its not editable.
Below is the code adding JS to pdf which is not merged yet.
FileOutputStream section1Pdf = new FileOutputStream("newPDFSection");
PdfReader readerSection1 = new PdfReader("Existing PDF - Section 1");
PdfStamper stamperSection1 = new PdfStamper(readerSection1,section1Pdf);
stamperSection1.addJavaScript(
"var nameField = this.getField('txtOwnerCity');" + "nameField.setAction('Keystroke'," +"'forceUpperCase()');" +
"" +"function forceUpperCase(){" +
"if(!event.willCommit)event.change = " +
"event.change.toUpperCase();" +
"}");
When I tried adding JS to the resulting merged pdf, it does not allow me saying it is not editable anymore.
This is how I am trying to add
FileOutputStream sectionR = new FileOutputStream(RESULT);
PdfCopyFields copier = new PdfCopyFields(sectionR);
for (String curInPath : listFile) {
PdfReader reader = new PdfReader(curInPath);
copier.addDocument(reader);
}
copier.close();
PdfReader readersectionResult = new PdfReader("result.pdf");
PdfStamper stamper = new PdfStamper(readersectionResult, new FileOutputStream("newResult.pdf"));
stamper.addJavaScript(some JS);
The error I am getting is ' WARNING: Cannot set header. Response already committed.'
I am not sure if I am doing it right above, All I am trying to do is get pdfstamper of resulting pdf to add new JS to it.
When I am trying to edit form filed values, it says not editable anymore.
AcroFields acro= stamper .getAcroFields();
acro.setField("txtOfficerName"+officerChar,officerSO.getFullName());

Using ContentByteUtils for raw PDF manipulation

This is a follow up question to:
Programmatically change the color of a black box in a PDF file?
I have a pdf I created in Illustrator that has basically a black shape in the middle of the page and nothing else. I need to change the color of that shape dynamically.
From the response to the post above I am using iTextSharp (.NET C#) to get the raw contents of the PDF through ContentByteUtils.GetContentBytesForPage() and changing the color at the raw level.
Problem is that I can't find any way of saving the results back into either the original PDF or a new PDF file via iTextSharp. I'm currently stuck with a byte array of the raw contents but need to figure out how to save.
Help please!
Why are you using ContentByteUtils.GetContentBytesForPage()?
I would use:
PdfReader reader = new PdfReader(src);
byte[] content = reader.GetPageContent(pageNumber);
// do stuff with content
reader.SetPageContent(pageNumber, content);
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (PdfStamper stamper = new PdfStamper(reader, fs)) {
}
}

How can I convert a web form to pdf using itextsharp?

I am trying to convert a web form to a pdf after a user fills in the fields in the web form. Is this possible? All i can do right now is loop through the form collection and print out the field name and the field value to the pdf. Is there a way to do this and keep the pdf looking like the web form?
I'm using mvc 3 for the web page.
Thanks!
Now I am using the following which converts everything in the form but the form fields.
Document doc = new Document();
String path = "C:\\projects\\pdfs\\";
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(path + "Doc1.pdf", FileMode.Create));
StringReader sr = new StringReader(htmlString);
HTMLWorker worker = new HTMLWorker(doc);
doc.Open();
worker.Parse(sr);
doc.Close();
How do I get the form fields to display in the pdf?