打开XML SDK:打开Word模板并保存到其他文件名

时间:2010-07-23 09:39:40

标签: openxml-sdk

这个非常简单的事情我找不到合适的技术。我想要的是打开.dotx模板,进行一些更改并保存为.docx扩展名相同的名称。我可以保存WordprocessingDocument但只能保存到它的加载位置。我尝试使用WordprocessingDocument手动构建一个新文档并进行了更改但到目前为止没有任何工作,我尝试了MainDocumentPart.Document.WriteTo(XmlWriter.Create(targetPath));并且只获得了一个空文件。

这里有什么正确的方法?就SDK而言,.dotx文件是特别的还是只是另一个文档 - 我应该只是将模板复制到目标,然后打开那个并进行更改,然后保存?如果我的应用程序可以同时从两个客户端调用,我确实有一些问题,如果它可以打开两次相同的.dotx文件...在这种情况下创建一个副本将是明智的...但是为了我自己的好奇心,我仍然想要知道怎么做“另存为”。

2 个答案:

答案 0 :(得分:6)

我建议只使用File.IO将dotx文件复制到docx文件并在那里进行更改,如果这适用于您的情况。还有一个ChangeDocumentType函数,你必须调用它以防止新的docx文件中出现错误。

            File.Copy(@"\path\to\template.dotx", @"\path\to\template.docx");

            using(WordprocessingDocument newdoc = WordprocessingDocument.Open(@"\path\to\template.docx", true))
            {
                newdoc.ChangeDocumentType(WordprocessingDocumentType.Document);
                //manipulate document....
            }

答案 1 :(得分:0)

虽然M_R_H的答案是正确的,但是有一种更快,IO占用更少的方法:

  1. 将模板或文档读入MemoryStream
  2. 在using语句中:
    • MemoryStream上打开模板或文档。
    • 如果您打开模板(.dotx)并想将其存储为文档(.docx),则必须将文档类型更改为WordprocessingDocumentType.Document。否则,当您尝试打开文档时,Word会抱怨。
    • 处理您的文档。
  3. MemoryStream的内容写入文件。

第一步,我们可以使用以下方法,该方法将文件读入MemoryStream

public static MemoryStream ReadAllBytesToMemoryStream(string path)
{
    byte[] buffer = File.ReadAllBytes(path);
    var destStream = new MemoryStream(buffer.Length);
    destStream.Write(buffer, 0, buffer.Length);
    destStream.Seek(0, SeekOrigin.Begin);
    return destStream;
}

然后,我们可以按以下方式使用它(尽可能多地复制M_R_H的代码):

// Step #1 (note the using declaration)
using MemoryStream stream = ReadAllBytesToMemoryStream(@"\path\to\template.dotx");

// Step #2
using (WordprocessingDocument newdoc = WordprocessingDocument.Open(stream, true)
{
    // You must do the following to turn a template into a document.
    newdoc.ChangeDocumentType(WordprocessingDocumentType.Document);

    // Manipulate document (completely in memory now) ...
}

// Step #3
File.WriteAllBytes(@"\path\to\template.docx", stream.GetBuffer());

请参见post,以比较克隆(或复制)Word文档或模板的方法。