最佳方法将FlowDocument转换为PDF是什么?

11

你们会如何建议我将FlowDocument转换为PDF并附加到电子邮件中?

FlowDocument是动态的,而不是静态的。

我希望能够将PDF存储在内存中作为byte[],而非存储在磁盘上,但这是可商量的。

感谢你们的帮助!


哦,我完全可以在这种情况下使用第三方控件。 - Joe
这个问题及其答案提供了另一种稍微有些hacky的解决方案。 - Peter Taylor
7个回答

4
免责声明:我是XamlToPDF库的作者,但该库可供任何类型的使用,且免费。

http://xamltopdf.codeplex.com/

创建PDF非常简单,它还支持表格和图片。


@PeterTaylor 不,它不是这样的!! - Akash Kava
1
我的错:只有测试项目依赖于AxAcroPDFLib。 - Peter Taylor
1
这个解决方案似乎不支持图像对象,但对我来说其他方面都很好用。 - Scott

4
我假设您希望以编程方式而非手动过程来完成此操作。
方法1:安装PDF驱动程序,如AmyuniPrimoPDF。使用所需的PrintTicket /页面大小将FlowDocument打印到打印驱动程序中。从中获得的PDF应该是相当好的转换。其中一些驱动程序(如Amyuni)具有您可以以编程方式控制此过程的SDK。
方法2:使用XPS驱动程序以编程方式打印XPS,而无需“另存为”对话框; Windows DDK中有一个示例,您可以相当轻松地构建它自己。然后使用XPS到PDF转换器,例如NiXPS或Adobe SDK(价格昂贵,我不会发布链接),或GhostXPS将XPS直接转换为PDF。 方法三:使用类似这个的方法将流文档直接转换为XPS,然后使用上述提到的XPS转PDF转换器进行转换。

免责声明:我不为任何这些公司或它们的竞争对手工作。我已经使用过Adobe SDK、Amyuni打印机和各种XPS技巧,并取得了相当不错的成功。没有一种方法能够100%准确地转换。


1
Amyuni PDF Creator .Net可以将XPS转换为PDF,而且它并不需要安装虚拟打印机,这是一个额外的好处。免责声明:我在Amyuni Technologies工作 - yms
1
我推荐使用第三种方法。FlowDocument 转 XPS 可以保留大部分格式。从 XPS 转 PDF 的质量可能会因所使用的工具而有所不同。 - TheZenker

2
您有我知道的两个选项。
第一个是使用一个叫做 NiPDF 的专有库,或者您可以使用 Word Interop。
  1. 使用 Open XML SDK 将 FlowDocument 保存为 DOCX 文件
  2. 使用 Word Interop 从某个临时存储中加载保存的文档
  3. WdSaveFormat 设置为 wdFormatPDF
  4. 再次保存文档(记得将文件重命名为 PDF)
您可以在 这里 找到更多信息。

NiPdf只能处理FixedDocuments。我需要一个可以处理FlowDocument的解决方案。 - Joe
该网站有误导性,NiPDF允许您将可视化内容转换为PDF...没有任何阻止您获取FlowDocument可视化内容的限制。 - Stefan Z Camilleri
2
小心第一步,它很棘手! - TheZenker
1
我最终使用了NiPDF。效果非常好。 - Joe
实际上,这是通过编写自己的FlowDoc到OpenXML解析器/转换器来完成的。 :-) - TheZenker

1

当我需要做这件事情时,我将FlowDocument保存为XPS文件,最后使用PDFSharp转换为PDF并删除XPS文件。

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);

希望这能帮助到某些人


1

我成功地使用PDFCreator打印机驱动程序使其工作。您需要安装该驱动程序才能使其正常工作,因此对于某些人来说可能不是理想的解决方案。有一个可用的COM接口。代码大致如下:

        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");

1
新版本与以往有很大不同,我创建了一个包装器,您可以使用它来执行此操作 new PdfCreatorComWrapper().CreatePdf(DocumentPaginator, filename); 包装器源代码可在 GitHub 上获取。 - Louis Somers

0
你可能想考虑一下Seberix开发的名为“Report Writer for .NET”的产品(http://www.siberix.com/)。 它的API与FlowDocument中的后置代码类似,这正是您在说“动态而非静态”时想要的内容。 (但我确定也存在差异。魔鬼就在于细节)。
一旦创建了Siberix.Report.Report对象,
Siberix.Report.Report report = CreateMyPdfReport();  //You write this
Stream stream = new MemoryStream();
report.Publish(stream, Siberix.Report.FileFormat.PDF);
byte[] bytes = stream.ToArray();

现在字节可以保存到数据库表或其他任何地方。


0

它首先将XPS文件写入临时文件夹,然后使用免费的社区版本Spire.PDF将XPS文件转换为PDF。社区版仅限于10页。 - Louis Somers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接