场景是这样的,根据模板文档生成目标文档,模板文档中会有一个附件,这个附件本身也是模板,我会根据模板附件生成一个新的附件,再调用InsertOleObjectAsIcon接口将新附件嵌入到目标文档中,同时也调用Save接口将新附件保存到本地,保存到本地的附件是能打开的且数据是正常的,但是双击目标文档中的附件总是报异常(Aspose.Words.dll为23.9版本,基于wps测试的,异常图片在附件中),打不开,这是什么原因呢?
我的测试场景相对复杂,还涉及到数据库的,我全部替换成用微软的office工具了,双击附件仍会报这种异常,大概会是什么原因呢?我是直接用附件模板的progId生成附件再嵌入到word中的,然后图标名字传的null,就使用默认图标生成了
您好,我复现出来了,以下是demo,文件在附件中:
Aspose.Words.Document docTemplate = new Aspose.Words.Document("测试.docx");
Aspose.Words.Document doc = new Aspose.Words.Document();
DocumentBuilder documentbuilderDestination = new DocumentBuilder(doc);
MemoryStream memorystreamTemplate = null;
NodeCollection nodecollection = docTemplate.FirstSection.Body.GetChildNodes(NodeType.Shape, true);
try
{
foreach (Node node in nodecollection)
{
memorystreamTemplate = new MemoryStream();
((Shape)node).OleFormat.Save(memorystreamTemplate);
Aspose.Cells.Workbook workbookTemplate = new Aspose.Cells.Workbook(memorystreamTemplate);
Aspose.Cells.Workbook workbookDestination = new Aspose.Cells.Workbook();
workbookDestination.Copy(workbookTemplate);
documentbuilderDestination.MoveToDocumentEnd();
documentbuilderDestination.InsertOleObjectAsIcon(workbookDestination.SaveToStream(), ((Shape)node).OleFormat.ProgId, null, "用户工作流清单.xlsx");
}
doc.Save("目标.docx");
}
finally
{
if (memorystreamTemplate != null)
memorystreamTemplate.Close();
}
Demo.zip (75.6 KB)
运行结果现象:生成的目标文件中,双击用户工作流清单附件,报异常
@jumy 感谢您提供更多信息。 代码中有两个错误。 第一个 - workbookDestination.SaveToStream()
返回 MemoryStream
,位置设置为末尾,因此零字节被写入 OLE 对象。 第二个 - workbookDestination.SaveToStream()
将工作簿保存为 XLS,但原始的 ProgId
设置为 XLSX 格式。 因此,要使其正常工作,您应该修改以下代码:
documentbuilderDestination.InsertOleObjectAsIcon(workbookDestination.SaveToStream(), ((Shape)node).OleFormat.ProgId, null, "用户工作流清单.xlsx");
像这样:
using (MemoryStream ms = new MemoryStream())
{
workbookDestination.Save(ms, Aspose.Cells.SaveFormat.Xlsx);
ms.Position = 0;
documentbuilderDestination.InsertOleObjectAsIcon(ms, ((Shape)node).OleFormat.ProgId, null, "用户工作流清单.xlsx");
}
另外,还不太清楚为什么在这里使用 Aspose.Cells。 如果您的目标只是复制 OLE 对象,您可以修改代码,如下所示:
Document docTemplate = new Document(@"C:\Temp\in.docx");
Document doc = new Document();
DocumentBuilder documentbuilderDestination = new DocumentBuilder(doc);
NodeCollection nodecollection = docTemplate.FirstSection.Body.GetChildNodes(NodeType.Shape, true);
foreach (Node node in nodecollection)
{
using (MemoryStream memorystreamTemplate = new MemoryStream())
{
((Shape)node).OleFormat.Save(memorystreamTemplate);
documentbuilderDestination.MoveToDocumentEnd();
memorystreamTemplate.Position = 0;
documentbuilderDestination.InsertOleObjectAsIcon(memorystreamTemplate, ((Shape)node).OleFormat.ProgId, null, "用户工作流清单.xlsx");
}
}
doc.Save(@"C:\Temp\out.docx");
嗯,非常感谢,问题得到解决了。我的实际场景相对复杂,不是简单的复制OLE对象,要进行分析后再生成,所以要用到Aspose.Cells。