1

I'm having a little bit trouble changing from PdfStamper.AddFileAttachment that receives four arguments to PdfStamper.AddFileAttachment which recieves PdfFileSpecification object as an argument. The thing is i want to add files to my pdf document as an embedded files, Can some one tell me if i'm doing this the right way?!

I've replaced the : iText_Stamper.AddFileAttachment(desc, b, s, s);

with:

PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(iText_Stamper.Writer,
                            f.sDataFileName, s, b);
                        pfs.AddDescription(desc, true);
                        iText_Stamper.AddFileAttachment(desc, pfs);

                        PdfTargetDictionary target = new PdfTargetDictionary(true);
                        target.EmbeddedFileName = s;
                        PdfDestination dest = new PdfDestination(PdfDestination.FIT);
                        dest.AddFirst(new PdfString(desc));
                        iTextSharp.text.pdf.PdfAction action = iTextSharp.text.pdf.PdfAction.GotoEmbedded(null, target,
                            dest, true);
                        Chunk chunk = new Chunk(desc);
                        chunk.SetAction(action);
                        iText_Stamper.Writer.Add(chunk);

Is this sufficient? am i doing it right? I'll be glad for some help.

Biryukov Pavel
  • 397
  • 4
  • 18
  • What makes you suspect you are doing something wrong? What is different from your expectations? – mkl Dec 27 '15 at 14:00
  • i followed this thread: [link](http://stackoverflow.com/questions/16687631/attaching-files-to-a-pdf) for a proper solution. looks fine but my document is of a type: **Winnovative.PdfCreator.Document** and there is no method which accepts chunk type, though i cannot finish. – Biryukov Pavel Dec 27 '15 at 14:11
  • *my document is of a type: `Winnovative.PdfCreator.Document`* - so you are using a `Document` from a different pdf library and wonder why it behaves differently? – mkl Dec 27 '15 at 16:34
  • threw PdfStamper there is a way to get the writer and add the chunk to it. but still it doesn't work. – Biryukov Pavel Dec 29 '15 at 14:12
  • *to get the writer and add the chunk to it.* - what chunk do you mean? I don't see anything in your question that indicates that you want to add done chunk. – mkl Dec 29 '15 at 14:28
  • I've updated the code sample. – Biryukov Pavel Dec 30 '15 at 08:34
  • Ah, Now the problem becomes clearer. No, you cannot simply add chunks to the writer underlying the stamper like that. I'll give more details later, currently I'm on a smart phone only. – mkl Dec 30 '15 at 08:46

1 Answers1

0

The main issue in your code is that you assume that the PdfWriter descendant iText_Stamper.Writer can be used like a Document to which you can add text chunks using the Add method, and expect iTextSharp to layout such material automatically.

The class hierarchy unfortunately suggests this as both PdfWriter and Document implement the interface IElementListener which provides a method bool Add(IElement element).

Nonetheless, this assumption is wrong, the class hierarchies overlap for internal code reuse reasons, not to suggest similar usages; the Add implementation of the PdfWriter descendant iText_Stamper.Writer merely returns false and does not even attempt to add the given element to the document.

In particular in case of pages the stamper retrieved from the underlying PdfReader (and didn't add to them) this does make sense: If there is content somehow scattered across a page, where should the stamper add the new content? Should it consider the existing content background material and start at the top? Or should it somehow find a big unused page area and paint the elements there? (In case of newly added pages, though, the stamper indeed could have been programmed to serve like a regular PdfWriter and have allowed linkage with a Document to automatically layout content...)

Thus, to allow for new content to be automatically layout'ed, you have to tell iTextSharp where to put the content. You can do this by means of a ColumnText instance like this:

using (PdfReader reader = new PdfReader(source))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(result, FileMode.Create, FileAccess.Write)))
{
    PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(stamper.Writer, pdfPath, pdfName, pdfBytes);
    pfs.AddDescription(pdfDesc, true);
    stamper.AddFileAttachment(pdfDesc, pfs);

    PdfContentByte cb = stamper.GetOverContent(1);
    ColumnText ct = new ColumnText(cb);
    ct.SetSimpleColumn(30, 30, reader.GetPageSize(1).GetRight(30), 60);

    PdfTargetDictionary target = new PdfTargetDictionary(true);
    target.EmbeddedFileName = pdfDesc;
    PdfDestination dest = new PdfDestination(PdfDestination.FIT);
    dest.AddFirst(new PdfNumber(1));
    PdfAction action = PdfAction.GotoEmbedded(null, target, dest, true);

    Chunk chunk = new Chunk(pdfDesc);
    chunk.SetAction(action);
    ct.AddElement(chunk);
    ct.Go();
}

(I used somewhat more descriptive names than your f.sDataFileName, s, b)

In the course of layout'ing your chunks, ColumnText also establishes the desired goto-emebedded links.


By the way, from your writing embedded files and using a PdfAction.GotoEmbedded I assumed you attach another PDF. If that assumption happens to be wrong, you might want to use PdfAnnotation.CreateFileAttachment instead

mkl
  • 90,588
  • 15
  • 125
  • 265
  • at last i had used only `PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(iText_Stamper.Writer, f.sDataFileName, s, b); pfs.AddDescription(desc, true); iText_Stamper.AddFileAttachment(desc, pfs);` and that worked. found at [http://stackoverflow.com/questions/27823189/add-multiple-attachments-in-a-pdf-using-itext-pdf-stamper] – Biryukov Pavel Dec 31 '15 at 09:40
  • 1
    *and that worked* - your mentioning chunks made me think you also wanted to be able to open the pdf from the page *content*. If that is not required, that shorter code piece indeed will suffice. – mkl Dec 31 '15 at 11:22