3

Update:

After some discussion, we decided to go with TeX, specifically the windows compatible MiKTeX. We realised that even if we could get the dynamic lengthed table formatted by micromanaging the layout (which doesn't seem possible or is as tedious as calculating row height for each row), there are other dynamic controls like large text boxes that we would also need to micromanage so we decided to generate the whole doc on the fly. With that in mind, going to TeX was the obvious choice because of it's power and our prior experience with it and now after a week, I'm glad we went that way because all our reports are dynamically generated and the code behind is clean and minimal.

Original:

I've got a pdf form template generated using LiveCycle and I want to fill it in (pdfstamper) and add some tables (pdfptable), however it's proven to be more difficult than I initially thought.

I open a pdf and use pdfstamper to edit the static fields:

using (var outputPDF1 = new MemoryStream())
{
    var pdfReader = new PdfReader(pdf);
    var pdfStamper = new PdfStamper(pdfReader, outputPDF1);
    var pdfFields = pdfStamper.AcroFields;

    pdfFields.SetField("Field1", "Value1");

This is straight forward and clear.

Then I attempt to add a table that will go from a set location over several pages. There is an attempt of this here that is 3 years old with a much older version of itextsharp and it's very manual.

The crux of that code is to use GetOverContent to insert a ColumnText with the generated table however this requires knowing the table height and manually cutting the table to size

    var cb = pdfStamper.GetOverContent(1);
    var ct = new ColumnText(cb);
    ct.Alignment = Element.ALIGN_CENTER; 
    ct.SetSimpleColumn(36, 36, PageSize.A4.Width-36, PageSize.A4.Height-300); 
    ct.AddElement(table);
    ct.Go();

There is another answer Itextsharp: Adjust 2 elements on exactly one page which is limited to a single page table. It can be extendable but it seems like you'd have to calculate headers/footers as well on subsequent pages.

And various unanswered questions in the same general direction:

adding a dynamic Table to an pdf template

itextsharp place Pdfptable at desired position

So my question is, what is the current best way to statically create a pdf using a WYSIWYG editor and modify it to add dynamic sized content such as a table or arbitrary lengthed text? I don't want to generate one from scratch if we can use a WYSIWYG LiveCycle to get the template working, but if getting a table formatted for a pdf template takes more effort than generating the whole thing on the fly, then i'd rather generate the whole pdf on the fly using itextsharp.

Community
  • 1
  • 1
Joe
  • 11,147
  • 7
  • 49
  • 60

1 Answers1

0

First this: your code isn't ever going to work if you don't flatten the form. In a document created with LiveCycle Designer, the PDF acts as a container of XML. A PdfPTable can be used to create PDF syntax, which is very different from XML.

Secondly: in your code sample, you're adding a table OVER the existing content of the first page. Is this your intention? Why not create a separate document with a table, and then merge the document created from scratch with the filled-out and flattened form? Are you assuming that the existing content will reflow? In that case, you don't understand PDF, please do some more reading.

Suppose you are using this code:

var cb = pdfStamper.GetOverContent(1);
var ct = new ColumnText(cb);
ct.Alignment = Element.ALIGN_CENTER; 
ct.SetSimpleColumn(36, 36, PageSize.A4.Width-36, PageSize.A4.Height-300); 
ct.AddElement(table);
ct.Go();

If this works fine for you, except when the table doesn't fit one page, why don't you insert a second page? You're referring to an example where there's a line:

int status = ct.go(); 

You should use the value of status to find out if the table fits the column or not. As long as the table isn't rendered completely, you should insert pages, and add parts of the table to those new pages.

Of course: your design would be much better if you adapted your form, rather than inventing some 'hybrid' approach.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • First this: I do flatten the form. In LiveCycle, there is a choice to create a static PDF or a XFA, I choose the former, you're talking about the latter. Secondly: I can easily stamp one page and merge it with a generated table, this is not what the question is asking. There is a plethora of information existing that does what you are alluding to. The GetOverContent doesn't work fine for me, please read my question again if you don't understand this. Why don't I insert a second page? Please show me how you do this to a existing pdf with a table that spans more than 2 pages. – Joe Sep 12 '12 at 00:48
  • Of course my design would be much better if i "adapted" my form? So please sir, in your most enlightened state, teach us dim witted ones how you would do this. – Joe Sep 12 '12 at 00:49
  • You're getting my downvote because one, you failed to read the question, then you failed to answer the question, then you provided all fluff and no solution and to top that off, your attitude needs fixing. – Joe Sep 12 '12 at 00:53
  • OK, so you're using iTextSharp for free, and you choose to insult the original author of the library as well as the person who wrote two book on the subject. And still you expect an answer? – Bruno Lowagie Sep 12 '12 at 07:07
  • I downvoted the question because you say "The GetOverContent doesn't work fine for me" without explaining why it doesn't work fine. GetOverContent works perfectly to add content. Of course: if the content doesn't fit, you need to add more pages. How do you add more pages? Well, so far, you've only tried by insulting the author of iText and the iText in Action books. Maybe you'll have more success with the insertPage method: http://api.itextpdf.com/itext/com/itextpdf/text/pdf/PdfStamper.html#insertPage%28int,%20com.itextpdf.text.Rectangle%29 – Bruno Lowagie Sep 12 '12 at 07:11
  • I've reread your question. It doesn't say you flatten the form anywhere. Also you're not saying you're using the AcroForm part. Nowhere in your code I see you dispose of the XFA as I explained in my book "iText in Action - Second Edition" page 270. The fact that you didn't recognize my name leads to believe you didn't even bother reading the documentation. You're saying I have an attitude? That's the pot calling the kettle black. As for your solution, it's on page 178: http://1t3xt.be/?045 – Bruno Lowagie Sep 12 '12 at 07:25
  • I thank you for your solution, good on you for sharing it even though our bickering has gotten sour. However, your solution has the same flaw as your answer in that it incorrectly assumes I want to start a new page with the new content. I feel as if any more discussion between us will just lead to more flame and noise. Thank you for your input Bruno. – Joe Sep 12 '12 at 11:28
  • Sorry for not understanding. I understand that you want to add a table to an existing page. I understand that the table doesn't fit that page. What I don't understand: what do you want to happen with the part that doesn't fit, if you don't want to add an extra page??? Note that I never said you should add an extra page if the table fits! – Bruno Lowagie Sep 12 '12 at 11:49
  • Are you saying you have different static fields on different pages that you want to fill with table data? In that case, the answer is trivial, isn't it? You should get the field positions for all those fields, use the page variable in the GetOverContent method and the pos variable in the SetSimpleColumn method. If you don't have placeholders for the table, then your question is unanswerable, and you shouldn't downvote people who are trying to help. – Bruno Lowagie Sep 12 '12 at 11:57
  • Explain "I attempt to add a table that will go from a set location over several pages" because this is in contradiction with "[the answer] incorrectly assumes I want to start a new page." – Bruno Lowagie Sep 12 '12 at 12:00