FlowDocument转FixedDocument(经XPS中转)打印图片丢失求助
结合你提供的代码和场景,之前正常现在出现图片丢失,大概率和XPS打包过程中资源引用失效或Package生命周期管理不当有关,具体可以从以下几点排查:
图片资源未被正确嵌入XPS Package
FlowDocument中的图片如果使用本地文件路径(如C:\xxx.png)或相对URI,转XPS时不会自动将图片嵌入到创建的Package中。XPS是独立的打包文档,所有资源必须包含在Package内才能被FixedDocument正确读取。你的代码仅创建了空Package,未处理图片资源的嵌入,后续打印时FixedDocument无法找到外部图片资源,导致显示空白。Package关联的MemoryStream过早回收
你用MemoryStream创建Package,但未保持该Stream的存活状态。如果在获取FixedDocument后,MemoryStream被GC回收或关闭,Package内的资源(包括图片)会无法访问,打印时自然加载失败。Pack URI的唯一性与PackageStore冲突
代码固定使用pack://temp.xps作为URI,如果之前的Package未被彻底移除(比如异常流程导致PackageStore.RemovePackage未执行),新的Package可能无法正确覆盖,导致FixedDocument引用的是旧的、不含图片的Package资源。XPS写入后的资源未完成刷新
调用XpsDocumentWriter.Write(paginator)后,可能需要手动刷新Package并确保写入完成,再去获取FixedDocument。如果写入操作未完成就读取,可能导致图片资源还没被写入Package,从而无法显示。
针对性的修复建议
将图片嵌入FlowDocument的资源中
确保FlowDocument中的图片使用pack://格式的内部资源,或者在创建XPS前将图片文件添加到Package中:// 示例:将本地图片添加到Package var imagePartUri = new Uri("/images/photo.png", UriKind.Relative); var imagePart = package.CreatePart(imagePartUri, "image/png"); using (var fs = File.OpenRead("C:\\photo.png")) { fs.CopyTo(imagePart.GetStream()); } // 然后FlowDocument中的图片Source使用pack://temp.xps/images/photo.png保持MemoryStream的生命周期
不要让MemoryStream在FixedDocument使用前被回收,可以将其声明为类级变量,或者在打印完成后再释放:// 示例:将MemoryStream提升为类成员 private MemoryStream _xpsStream; // 创建XPS时 _xpsStream = new MemoryStream(); var package = Package.Open(_xpsStream, FileMode.Create, FileAccess.ReadWrite); // ...后续操作确保Pack URI的唯一性
避免固定使用同一个URI,可以生成唯一标识,比如:var uniqueUri = new Uri($"pack://temp_{Guid.NewGuid()}.xps"); PackageStore.RemovePackage(uniqueUri); PackageStore.AddPackage(uniqueUri, package);写入后强制刷新Package
在获取FixedDocument前,刷新并确保Package写入完成:XpsDocument.CreateXpsDocumentWriter(xps).Write(paginator); package.Flush(); // 强制刷新Package FixedDocument TESTE = xps.GetFixedDocumentSequence().References[0].GetDocument(true);
内容的提问来源于stack exchange,提问作者DigoPego

