PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Thu Mar 28, 2024 3:17 pm

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: Applying a template
PostPosted: Mon Jun 20, 2016 3:01 pm 
Offline

Joined: Mon Jun 20, 2016 2:54 pm
Posts: 7
Hi all,
I have a docx file which contains a stationery template (header and footer).
On the other side I have muti-page pdf documents which contain some information without headers and footers.

I would like to:

1) receive in input the multi-page pdf (Base64 encoded)
2) transform the docx file in a PDF (with another already purchased component)
3) apply the stationery template to all the pages of the input document (like printing over a phisical stationery)
4) send in output the document (Base64 encoded)

Language: C#

Any hints?

Thanks!


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Mon Jun 20, 2016 3:14 pm 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
Hi!

With PDFsharp it is simple to add a PDF page as stationary below the existing contents of a PDF page.
If the page contains black text on nothing, then the stationary will be visible.
If it has black text on a white rectangle, then the stationary will not be visible.

So to some extent the result depends on the "input" PDF files you have.

The Watermark sample shows how to draw text over or under the existing contents of a page.
http://www.pdfsharp.net/wiki/Watermark-sample.ashx
Try variation 2, but with DrawImage instead of DrawPath and without transformation.

The Graphics sample shows DrawImage at work:
http://www.pdfsharp.net/wiki/Graphics-s ... #Images_35

You can download the ZIP with the sample here:
http://pdfsharp.codeplex.com/releases/view/618773

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Mon Jun 20, 2016 4:15 pm 
Offline

Joined: Mon Jun 20, 2016 2:54 pm
Posts: 7
HI Thomas,
thanks for the kind and superquick reply.
Please apologize me but I've never worked with PDFSharp.

So the code would be:

Code:
// Open the template file as image
XImage image = XImage.FromFile(pdfTemplatePath);

// Open an existing document for editing and loop through its pages.
var document = PdfReader.Open(filename);
// Set version to PDF 1.4 (Acrobat 5) because we use transparency.
            if (document.Version < 14)
                document.Version = 14;

            for (var idx = 0; idx < document.Pages.Count; idx++)
            {
                var page = document.Pages[idx];

                // Get an XGraphics object for drawing beneath the existing content.
                var gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
             

                gfx.DrawImage(image);

            }
            // Save the document...
            document.Save(filename);


Correct?
The image (template) will be placed under the "document"?

Thanks!


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Tue Jun 21, 2016 7:46 am 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
The code looks good.

AFAIK you do not have to set the version to 14 - you need this for PNG and such with alpha blending, but not for templates.

You should specify position and size in the call to DrawImage.
gfx.DrawImage(image, 0, 0, page.Width, page.Height);

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Tue Jun 21, 2016 8:37 pm 
Offline

Joined: Mon Jun 20, 2016 2:54 pm
Posts: 7
Hi Thomas,
it seems to work correctly but, if I try to create an XImage from a Base64 coded documet, I get an "Invalid parameter" error.

Code:
byte[] bytes = System.Convert.FromBase64String(fileBase64);
MemoryStream ms = new MemoryStream(bytes);
XImage image= XImage.FromStream(ms);


Any hints?

Wile E


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Wed Jun 22, 2016 8:02 am 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
A code snippet from MigraDoc ("XImage CreateXImage(string uri)"):
Code:
if (uri.StartsWith("base64:"))
{
    string base64 = uri.Substring("base64:".Length);
    byte[] bytes = Convert.FromBase64String(base64);
    {
        Stream stream = new MemoryStream(bytes);
        XImage image = XImage.FromStream(stream);
        return image;
    }
}
return XImage.FromFile(uri);
You can prepend "base64:" to your BASE64 string and let MigraDoc do the decoding - just pass the string as a filename.

Maybe the problem is with the encoding side?

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Wed Jun 22, 2016 9:06 am 
Offline

Joined: Mon Jun 20, 2016 2:54 pm
Posts: 7
Hi Thomas,
I start from a physical PDF file to simulate in test a base64 in:

Code:
// simulate a base64 string in
Byte[] bytes = File.ReadAllBytes(path);

//byte[] bytes = System.Convert.FromBase64String(fileBase64);
MemoryStream ms = new MemoryStream(bytes);
XImage image= XImage.FromStream(ms);


If I analyze the code snippet you proposed, it looked really similar to the one used by me which causes an "Invalid parameter" error generated.

XImage CreateXImage(string uri) Code:
Code:
byte[] bytes = Convert.FromBase64String(base64);
using (Stream stream = new MemoryStream(bytes))
{
      XImage image = XImage.FromStream(stream);
      return image;
}


I'm missing something?
Please note that I use PDFsharp and not MigraDoc.

Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Wed Jun 22, 2016 9:50 am 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
Sorry, PDFsharp does not support the "base64:" prefix.

If you think there is something wrong with PDFsharp, then please provide a solution that allows us to replicate the problem.

It could help us if you'd show a complete stack trace for the "Invalid parameter" error.

BTW: Do not dispose the stream too early, I think PDFsharp stores a reference to the stream.

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Wed Jun 22, 2016 10:33 am 
Offline

Joined: Mon Jun 20, 2016 2:54 pm
Posts: 7
Hi Thomas,
I confirm I'm not using the "base64:" string.

The code that triggers the error (tested with a number of pdf files from different sources) is:

PDFSharp 1.50.4000-beta3b

Code:
protected void Page_Load(object sender, EventArgs e)
        {
                // simulate an imput a real PDF file
                Byte[] bytes = File.ReadAllBytes(@"D:\file5mb.pdf");
                MemoryStream stream = new MemoryStream(bytes);
                XImage image = XImage.FromStream(stream);     
        }


The Stack Trace is:

Code:
[ArgumentException: Invalid parameter.]
   System.Drawing.Image.FromStream(Stream stream, Boolean useEmbeddedColorManagement, Boolean validateImageData) +1402079
   PdfSharp.Drawing.XImage..ctor(Stream stream) +139
   PdfSharp.Drawing.XImage.FromStream(Stream stream) +43
   System.Web.UI.Control.OnLoad(EventArgs e) +109
   System.Web.UI.Control.LoadRecursive() +68
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4498


Thanks!


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Wed Jun 22, 2016 11:34 am 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
You have to call XPdfForm.FromStream if the stream contains a PDF file.

XImage.FromFile checks the extension and forwards ".pdf" to XPdfForm. XImage.FromStream does not handle PDF files automatically (yet).

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Wed Jun 22, 2016 2:56 pm 
Offline

Joined: Mon Jun 20, 2016 2:54 pm
Posts: 7
Hi Thomas,
please apologize me for this misunderstanding.

I'll try to explain better which is the aim of my request.

I'd like to develop a class that receives in imput a single page pdf file Template and a multi page pdf file Document.

we can consider the two PDF as a MemoryStream even if they could have different origin (base64, other APIs memory stream, pdf file, ..).

I came accross this post: viewtopic.php?f=2&t=149 vhich stated:

Quote:
you simply create a New PdfDocument and add a page to it. Then you declare XPdfForm.FromFile(InFile) and XPdfForm.FromFile(OverlayFile). Finally you declare an XGraphics.FromPdfPage(page) and use XGraphics.DrawImage to "paint" the XPdfForms, i.e. the contents of the desired pages from both InFile and OverlayFile onto the new page.


So, I suppose I will have to start with:
Code:
XPdfForm xpfTemplatePdf = XPdfForm.FromStream(xpfTemplateStream);

XPdfForm xpfMultiPagePdf = XPdfForm.FromStream(xpfMultiPageStream);


Can you please help me on the code to apply the xpfTemplatePdf "under" all the pages of xpfMultiPagePdf ?

Thankyou


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Wed Jun 22, 2016 3:12 pm 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
XPdfForm is a derived class of XImage.
You can use XPdfForm objects in calls to DrawImage as outlined in your code snippet above.

Use "Prepend" for the background so it will be drawn before the original contents of the page. Thus text on the original page will be drawn on the background image.

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Wed Jun 22, 2016 4:08 pm 
Offline

Joined: Mon Jun 20, 2016 2:54 pm
Posts: 7
Hi Thomas,
you rule.

I past the final code so that could be useful for any other user.

Code:
// Create the Template XPdf from a MemoryStream
XPdfForm xpfTemplatePdf = XPdfForm.FromStream(templateMS);

// Create a Document from a MemoryStream
var document = PdfReader.Open(docMS);

for (var idx = 0; idx < document.Pages.Count; idx++)
{
    var page = document.Pages[idx];

    // Get an XGraphics object for drawing beneath the existing content.
    var gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);

    gfx.DrawImage(xpfTemplatePdf, 0, 0, page.Width, page.Height);

}
// Save the document...
document.Save(@"D:\fattura.pdf");



Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Applying a template
PostPosted: Fri Nov 11, 2016 5:53 pm 
Offline

Joined: Fri Nov 11, 2016 5:31 pm
Posts: 1
Hi I'm trying to apply headers and footers to documents, they're almost perfect, but they're clipping a little bit along the bottom for some reason, I've included my code and the document. I've tried modifying the media box, adjusting the draw image of the form, changing the rect for the headergraphics onto the form, I'm not sure what else to try, they're both the same file going in, but when I use XPdfForm to add to the form it removes all the whitespace, which I was going for, but crops a little to closely

Code:
public PDFConcatenate(PackageToJoin pdfPackage)
        {
            MemoryStream outStream = new MemoryStream();

            CreateBaseDocument(pdfPackage).Save(outStream, false);
            ReturnFile = outStream.ToArray();
            DocName = pdfPackage.Name + ".pdf";
        }

        private PdfDocument CreateBaseDocument(PackageToJoin package)
        {
            OutputDocument = new PdfDocument();
            CreateHeaderAndFooter(package);
            foreach (var chunk in package.Chunks)
            {
                InputDocument = PdfReader.Open(new MemoryStream(chunk.Data), PdfDocumentOpenMode.Import);
               
                int count = InputDocument.PageCount;

                for (int idx = 0; idx < count; idx++)
                {
                    PdfPage page = InputDocument.Pages[idx];               
                    OutputDocument.AddPage(page);
                    AddHeaderFooter(OutputDocument.Pages[OutputDocument.PageCount-1], chunk.UseHeaderFooter);                 
                }
            }
            return OutputDocument;
        }

        private void AddHeaderFooter(PdfPage page, HeaderAndFooter headersAndFooters)
        {
            XGraphics gfx = XGraphics.FromPdfPage(page);

            if (headersAndFooters.ApplyHeader)
            {
                XRect adjustedHeaderRect = new XRect(5, 5, HeaderRect.Width,
                    HeaderRect.Height);
                gfx.DrawImage(Header, adjustedHeaderRect);
            }

            if (headersAndFooters.ApplyFooter)
            {
                XRect adjustedFooterRect = new XRect(5, page.Height - FooterRect.Height - 5, FooterRect.Width,
                    FooterRect.Height);
                gfx.DrawImage(Footer, adjustedFooterRect);
            }
            gfx.Dispose();
        }

        private void CreateHeaderAndFooter(PackageToJoin package)
        {
            //assign header form
            var rawHeader = PdfReader.Open(new MemoryStream(package.HeaderData), PdfDocumentOpenMode.Import);
            PdfPage page = rawHeader.Pages[0];
            HeaderRect = new XRect(0,0, page.Width, page.Height);
            Header = new XForm(OutputDocument, page.Width, page.Height);
            XGraphics headGraphics = XGraphics.FromForm(Header);
            headGraphics.DrawImage(XPdfForm.FromStream(new MemoryStream(package.HeaderData)), HeaderRect);
            headGraphics.Dispose();
           
            //assign footer form
            var rawFooter = PdfReader.Open(new MemoryStream(package.FooterData), PdfDocumentOpenMode.Import);
            page = rawFooter.Pages[0];
            FooterRect = new XRect(0,0, page.Width, page.Height);
            Footer = new XForm(OutputDocument, page.Width, page.Height);
            XGraphics footGraphics = XGraphics.FromForm(Footer);
            footGraphics.DrawImage(XPdfForm.FromStream(new MemoryStream(package.FooterData)), FooterRect);
            footGraphics.Dispose();
        }


Attachments:
HeaderOnDoc.PNG
HeaderOnDoc.PNG [ 38.77 KiB | Viewed 13397 times ]
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC


Who is online

Users browsing this forum: Bing [Bot] and 130 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group