我可以使用现有的WPF(XAML)控件,对其进行数据绑定并将其转换为可以使用WPF XPS文档查看器显示和打印的XPS文档吗?如果是这样,怎么样?如果没有,我应该如何使用XPS/PDF /等在WPF中进行"报告"?
基本上我想采用现有的WPF控件,数据绑定它以获取有用的数据,然后使其可打印并可供最终用户保存.理想情况下,文档创建将在内存中完成,除非用户专门保存文档,否则不会访问磁盘.这可行吗?
我想创建一个用于存储和打印的XPS文档.
在我的程序中创建XPS文档的最简单方法是什么(例如,在其中包含一些带有一些数据的简单网格),并传递它?
当我阅读有关WPF的书籍时,我看到作者提到XPS就像它是重要的东西.Windows还包括其XPS查看器,我已经看到它被列为Windows的"功能".
但为什么?重点是什么?谁用它呢?我的理解是,XPS基本上就像PDF,xhtml或ePub(只是xhtml)......甚至是Word的docx格式.这些格式中的许多功能都是相同的.
与任何其他格式相比,它似乎没有任何重大好处.在我看来,xhtml比XPS更有用,作为从RichTextBox保存和加载FlowDocuments的一种方法.我看过多个关于两者之间转换的博客.互联网上的大部分或全部富文本都是(x)html.除此之外,我认为没有人只是用它来发表他们的文档; PDF是首选.似乎XPS只是MS制作并决定推出的一些随机格式.我一般都喜欢MS,但他们确实有这种习惯.MS不能使用xhtml制作api吗?我想,在很多情况下,这会更有用.
那么,有没有必要使用XPS,特别是与我提到的其他格式(或任何我没有的)相比较?你有没有在你的程序中使用过XPS?
我从XAML用户控件生成的XPS文档充当模板.我想将XPS文档转换为替代格式,主要是PDF,使用基于.NET的API编程.
做这个的最好方式是什么?
我已经在标准WPF控件中实现了一个报表,并且还实现了一个DocumentPaginator来获取这些控件并将它们转换为一个文档进行打印.
我还实现了一些代码,它们使用文档分页器将页面呈现为图像,并使用PDFSharp将它们写入PDF ,但是这不允许复制和粘贴,图像质量也有问题.
我已经尝试过使用GhostXPS实用程序并考虑通过保存到XPS文档然后使用GhostXPS将其转换为PDF来使用它,这很有希望,但是当前版本包含一个错误,该错误会从生成的PDF中复制数据无用...
所以我想我会在这里尝试找到一种有效的方法来做到这一点,有人可以建议一个好的方法来获取DocumentPaginator并直接将其保存为PDF,具有复制/粘贴功能或从XPS文档转换它到具有此功能的PDF?
谢谢,亚历克斯.
编辑 - PDFSharp修复:这里要求的是我为编译PDFSharp 1.31 XPS转换器的修复程序所做的工作:
1)我从这里下载了源代码:
2)我按照这篇文章中的说明:
XpsParser.ImageBrush.cs (ln 22, added): brush.Opacity = 1;
PdfContentWriter.cs (ln 526, changed): if (opacity <= 1)
Run Code Online (Sandbox Code Playgroud)
3)然后只需编译源代码,首先打开'PdfSharp-WPF.csproj'并构建它,然后打开'PdfSharp.Xps.csproj'并构建它,相关的库是'PdfSharp-WPF.dll'和'PdfSharp.Xps.dll'
注意,在尝试构建源代码时,您可能会收到一些错误,具体取决于您所针对的.NET版本,如果您只是阅读错误消息,这些错误很容易修复.
编辑(2):NJones创建了一篇博文,其中详细介绍了PdfSharp修复:在WPF中输出为PDF
我需要告诉打印机驱动程序发出换页.
我使用以下方法直接打印到打印机:
一组API调用.
很多灵感来自KB138594 - HOWTO:使用Win32 API将原始数据发送到打印机.知识库文章中需要注意的一点是,它们(以及我复制的代码)以RAW模式启动文档:
// Fill in the structure with info about this "document."
docInfo.pDocName = "My Document";
docInfo.pOutputFile = NULL;
docInfo.pDatatype = "RAW";
StartDocPrinter(hPrinter, 1, docInfo);
Run Code Online (Sandbox Code Playgroud)
注意:
RAW模式(与模式相反TEXT)意味着我们向打印机驱动程序发出原始字节.我们承诺用它理解的语言进行交谈.
然后我们可以WritePrinter用来写我们想要的一切:
WritePrinter(hPrinter, "Hello, world!"); //note, extra parameters removed for clarity
WritePrinter(hPrinter, 0x0c); //form-feed
Run Code Online (Sandbox Code Playgroud)
这里的问题是0x0c换页字符.因为我们已经在RAW模式下打开了打印机,我们承诺我们将发送它可以处理的打印机驱动程序字节.大多数打印机的驱动程序0x0C意味着您要发布换页.
问题是其他打印机(PDF打印机,Microsoft XPS打印机)希望RAW打印作业使用他们自己的打印机语言.如果您使用上述内容打印到XPS或PDF打印机:没有任何反应(即没有保存对话框,没有打印).
我正在尝试使用WPF转换XPS.
想法是这些图像可以加载silverlight 4,为此我使用以下代码:
// XPS Document
XpsDocument xpsDoc = new XpsDocument(xpsFileName, System.IO.FileAccess.Read);
FixedDocumentSequence docSeq = xpsDoc.GetFixedDocumentSequence();
// The number of pages
PageCount = docSeq.References[0].GetDocument(false).Pages.Count;
DocumentPage sizePage = docSeq.DocumentPaginator.GetPage(0);
PageHeight = sizePage.Size.Height;
PageWidth = sizePage.Size.Width;
// Scale dimensions from 96 dpi to 600 dpi.
double scale = 300/ 96;
// Convert a XPS page to a PNG file
for (int pageNum = 0; pageNum < PageCount; pageNum++)
{
DocumentPage docPage = docSeq.DocumentPaginator.GetPage(pageNum);
BitmapImage bitmap = new BitmapImage();
RenderTargetBitmap renderTarget =
new …Run Code Online (Sandbox Code Playgroud) 我试图从WPF控件生成XPS文档.到目前为止,打印工作,但我找不到在横向模式下创建XPS的方法.
我创建XPS文件的代码,主要来自另一个SO页面
public FixedDocument ReturnFixedDoc()
{
FixedDocument fixedDoc = new FixedDocument();
PageContent pageContent = new PageContent();
FixedPage fixedPage = new FixedPage();
var ctrl = new controlToPrint();
//Create first page of document
fixedPage.Children.Add(ctrl);
((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
fixedDoc.Pages.Add(pageContent);
//Create any other required pages here
return fixedDoc;
}
public void SaveCurrentDocument()
{
// Configure save file dialog box
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "MyReport"; // Default file name
dlg.DefaultExt = ".xps"; // Default file extension
dlg.Filter = "XPS Documents (.xps)|*.xps"; // Filter files …Run Code Online (Sandbox Code Playgroud) 我正在开发一个打开并显示XPS文档的WPF应用程序.当应用程序关闭时,规范是应用程序应该删除打开的XPS文档以进行清理.但是,在打开某个XPS文档时,应用程序会在尝试删除该文件时抛出该文件仍在使用的异常.这有点奇怪,因为它只在打开特定的XPS文档时才会发生,并且只有在您超出第一页时才会发生.
我使用的一些代码如下所示:
要打开XPS文档:
DocumentViewer m_documentViewer = new DocumentViewer();
XpsDocument m_xpsDocument = new XpsDocument(xpsfilename, fileaccess);
m_documentViewer.Document = m_xpsDocument.GetFixedDocumentSequence();
m_xpsDocument.Close();
Run Code Online (Sandbox Code Playgroud)
用于导航XPS文档:
m_documentViewer.FirstPage();
m_documentViewer.LastPage();
m_documentViewer.PreviousPage();
m_documentViewer.NextPage();
Run Code Online (Sandbox Code Playgroud)
要关闭DocumentViewer对象并删除文件:
m_documentViewer.Document = null;
m_documentViewer = null;
File.Delete(xpsfilename);
Run Code Online (Sandbox Code Playgroud)
这一切都非常基础,它适用于我们测试的其他文档.但是对于特定的XPS文档,会弹出一个异常,说明要删除的文件仍在使用中.
我的代码有什么问题或遗漏吗?
谢谢!
我想从我的WPF应用程序生成(然后打印或保存)大型XPS文档(> 400页).我们有一些需要写入XPS的大量内存数据.
如果没有得到一个OutOfMemoryException怎么办呢?有没有办法可以把文件写成块?这通常是怎么做的?我不应该首先将XPS用于大文件吗?
这个根本原因OutOfMemoryException似乎是巨大的创造FlowDocument.我正在创建完整FlowDocument,然后将其发送到XPS文档编写器.这是错误的方法吗?