11

How would ya'll recommend that I convert a FlowDocument to PDF to be attached to an EMail?

The FlowDocument is dynamic, not static.

I would prefer to be able to store the PDF in memory as a byte[], rather than on disk, but that is negotiable.

Thanks for your help!

Joe
  • 669
  • 1
  • 8
  • 21

7 Answers7

4

Disclaimer: I am writer of XamlToPDF Library, however it is free for any type of use.

http://xamltopdf.codeplex.com/

Its very easy to create PDF, it supports Tables and images as well.

Akash Kava
  • 39,066
  • 20
  • 121
  • 167
4

I am assuming you want this to occur programmatically rather than as a manual process.

Method 1: Install a PDF driver such as Amyuni or PrimoPDF. Print your FlowDocument with the desired PrintTicket / page size, to the print driver. The PDF you get from it should be a fairly good conversion. Some of these drivers (such as Amyuni) have SDKs that you can control this process programmatically.

Method 2: Print to XPS programmatically using an XPS driver without a Save As dialog; there's a sample for this in the Windows DDK you can build yourself fairly easily. Then use an XPS to PDF converter such as NiXPS or the Adobe SDK (so expensive I won't post a link) or GhostXPS to convert the XPS directly to PDF.

Method 3: Convert the flow document directly into XPS using methods like This one and then use an XPS to PDF converter such as the ones mentioned above.

Disclaimer: I don't work for any of these companies or their competitors. I've used the Adobe SDK, the Amyuni printer, and various XPS tricks with fairly good success. No method will convert with 100% accuracy.

Ed Bayiates
  • 11,060
  • 4
  • 43
  • 62
  • 1
    [Amyuni PDF Creator .Net](http://www.amyuni.com/en/developer/pdfcreator/features) can also convert from XPS to PDF, as a plus, it does not need a virtual printer to be installed. *Disclaimer: I do work for Amyuni Technologies* – yms Feb 08 '12 at 14:20
  • 1
    I recommend Method 3. FlowDocument to XPS can be done with little loss of formatting. From XPS to PDF quality will likely vary based on tool used. – TheZenker Feb 08 '12 at 14:46
2

You have two options that I know of.

The first is to use a proprietary library called NiPDF, alternatively you can use Word Interop.

  1. Save the FlowDocument to a DOCX file using Open XML SDK
  2. Use Word Interop to load the saved document from some temporary store
  3. Set the WdSaveFormat to wdFormatPDF
  4. Save the document again (remember to rename the file to PDF)

You can find further info here

Stefan Z Camilleri
  • 4,016
  • 1
  • 32
  • 42
1

I managed to get this working with the PDFCreator printer driver. You need to install the driver for this to work, so it may not be an ideal solution for some people. There is a COM interface available. The code more or less looks something like this:

        PDFCreator.clsPDFCreator _PDFCreator;
        PDFCreator.clsPDFCreatorError pErr;


        if (_PDFCreator.cStart(parameters, false))
        {
            _PDFCreator.cClearCache();
            _PDFCreator.set_cOption("UseAutosave", 1);
            _PDFCreator.cPrinterStop = false;
        }

        _PDFCreator.set_cOption("AutosaveFilename", file);
        _PDFCreator.set_cOption("AutosaveDirectory", folder);

    PrintDialog printDialog = new PrintDialog();                          
    printDialog.PrintDocument(((IDocumentPaginatorSource)flowDoc).DocumentPaginator, "Report");
Brian
  • 6,910
  • 8
  • 44
  • 82
  • 1
    The new version is quite different, I made a wrapper with witch you can do this `new PdfCreatorComWrapper().CreatePdf(DocumentPaginator, filename);` The wrapper source is available [on GitHub](https://github.com/mlsomers/PdfForgePdfCreatorWrapper). – Louis Somers Sep 08 '19 at 01:17
1

When I needed to do this I saved the FlowDocument as an XPS file and finally converted to PDF with PDFSharp and deleted the XPS file

var test = (IDocumentPaginatorSource)flowDoc;
XpsDocument xpsDocument = new XpsDocument(xpsFileLocation, FileAccess.ReadWrite);
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
writer.Write(test.DocumentPaginator);
xpsDocument.Close();            

PdfSharp.Xps.XpsConverter.Convert(xpsFileLocation, pdfFileLocation, 0);
File.Delete(xpsFileLocation);

Hope this helps someone

SCREwart
  • 11
  • 3
0

Another option to look at is FlowDocumentConverter. This is available in a NuGet package, but per documentation does have a 10 page limitation.

Scott
  • 1,223
  • 2
  • 16
  • 35
  • It first writers an XPS file to the temp folder and then uses the free community version of [Spire.PDF](https://www.e-iceblue.com/Introduce/pdf-for-net-introduce.html) to convert the XPS file to PDF. The community version is limited to 10 pages. – Louis Somers Aug 17 '19 at 14:46
0

You might want to consider the product called "Report Writer for .NET" by Seberix (http://www.siberix.com/). Its API is similar to the code behind in FlowDocument which I think is you want want when you said "dynamic, not static". (But I'm sure there are differences as well. Devils are in the details).

Once a Siberix.Report.Report object has been created,

Siberix.Report.Report report = CreateMyPdfReport();  //You write this
Stream stream = new MemoryStream();
report.Publish(stream, Siberix.Report.FileFormat.PDF);
byte[] bytes = stream.ToArray();

Now bytes can be saved to a database table or whatever.

Kevin Le - Khnle
  • 10,579
  • 11
  • 54
  • 80