其行为如下:下载在服务器上动态创建的文档,然后在Mac上打开该文档后,该文档将不会“另存为”。它会自动失败,将文档名称设置为以前的名称,并且在保存目标文件夹中没有文档。
内幕:代码创建文档并附加文本,然后在该文件的末尾附加由另一个人为该创建的文档上载的word文档。该代码使用的是AltChunk
类,如MSDN文档here中所述。这样效果很好,除了间歇性地使用上述某些附件外,没有什么其他问题。
这似乎是一个单词错误,我不确定在用文字或OpenXML修补此错误之前,我是否可以做任何事情。
以下是重现此错误所需的步骤:
DocumentFormat.OpenXml
创建一个名为“ test-append.docx”的新单词文档(嵌入式单词doc)
复制将以下代码粘贴到您的Program.cs
文件中:
using System.IO;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using Text = DocumentFormat.OpenXml.Wordprocessing.Text;
namespace TestWordAppend
{
class Program
{
static void Main(string[] args)
{
var destinationDoc = "Docs/test-destination.docx";
var sourceDoc = "Docs/test-source.docx";
var appendedDoc = "Docs/test-append2.docx";
File.Delete(destinationDoc);
File.Copy(sourceDoc, destinationDoc);
using (var doc = WordprocessingDocument.Open(destinationDoc, true))
{
var body = doc.MainDocumentPart.Document.Body;
var p2 = body.InsertAfter(
new Paragraph(
new ParagraphProperties(
new PageBreakBefore()
)),
body.Elements<Paragraph>().Last()
);
var altChunkId = "AltChunkId";
var chunk = doc.MainDocumentPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML,
altChunkId);
using (var fs = File.Open(appendedDoc, FileMode.Open))
chunk.FeedData(fs);
var altChunk = new AltChunk { Id = altChunkId };
var run = new Run(new TabChar(), new Text(appendedDoc), new Break());
run.PrependChild(new RunProperties { RunStyle = new RunStyle { Val = "Bold" } });
var fileP = p2.InsertAfterSelf(new Paragraph());
fileP.Append(run);
run = new Run(new TabChar(), new Text("Uploaded by: "), new TabChar(), new Text("Test User"));
run.PrependChild(new RunProperties { RunStyle = new RunStyle { Val = "Italic" } });
fileP.Append(run);
body.Append(altChunk);
doc.MainDocumentPart.Document.Save();
}
}
}
}
~/bin/Debug/netcoreapp.3.0/Docs/test-destination.docx
中的文档,其中~
是解决方案所在的基本路径。~/Documents
文件夹中进行“另存为”,其中~
是用户的主路径。答案 0 :(得分:0)
我找到了另一种可以帮助缓解此问题的解决方案,但我认为这只是一种解决方法。我已将此错误发布到OpenXML。我不确定这是否实际上是OpenXML的问题,似乎可能是Word引起的,但至少在某个地方引发并指出了该问题。
否则,我不得不在下面找到此解决方案。相反,我必须遍历每个元素并将其克隆,然后将其附加到源文档中。 如果克隆的元素中有图像,则必须执行一些额外的步骤,以将图像复制到新文档中。
private static void GenerateByCopying()
{
using (var doc = WordprocessingDocument.Open(DestinationDoc, true))
using (var appendedDoc = WordprocessingDocument.Open(AppendedDoc, true))
{
var body = doc.MainDocumentPart.Document.Body;
var appendedBody = appendedDoc.MainDocumentPart.Document.Body;
AppendNecessaryText(body);
foreach (var part in appendedBody.Elements())
{
var clonedElement = part.CloneNode(true);
clonedElement.Descendants<DocumentFormat.OpenXml.Drawing.Blip>()
.ToList()
.ForEach(imageData =>
{
var newRelation = CopyImage(doc, imageData.Embed, appendedDoc);
imageData.Embed = newRelation;
});
clonedElement.Descendants<DocumentFormat.OpenXml.Vml.ImageData>()
.ToList()
.ForEach(imageData =>
{
var newRelation = CopyImage(doc, imageData.RelationshipId, appendedDoc);
imageData.RelationshipId = newRelation;
});
body.Append(clonedElement);
}
doc.MainDocumentPart.Document.Save();
}
}
public static string CopyImage(WordprocessingDocument doc, string relId, WordprocessingDocument source)
{
var p = source.MainDocumentPart.GetPartById(relId) as ImagePart;
var np = doc.MainDocumentPart.AddPart(p);
np.FeedData(p.GetStream());
return doc.MainDocumentPart.GetIdOfPart(np);
}
调整控制台应用程序,在File.Copy()
之后运行此方法,我确实能够使用图像打开文档并保存更改。