添加 CustomXmlPart 后 Word 无法打开文档
Word can't open document after adding CustomXmlPart
我正在尝试将自定义xml部件添加到 docm 文件,但没有成功。
显然文件太大(超过 10mb)无法包含在包中。
如果 xml 文件大小小于 7 mb,则可以成功打开文档。
有什么想法吗?
感谢您的帮助。
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open("doc.docm", true))
{
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
if (wordDoc.MainDocumentPart.CustomXmlParts != null)
{
wordDoc.MainDocumentPart.DeleteParts<CustomXmlPart>(wordDoc.MainDocumentPart.CustomXmlParts);
}
CustomXmlPart myXmlPart = mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
using (FileStream stream = new FileStream("10mbfile.xml", FileMode.Open))
{
myXmlPart.FeedData(stream);
}
wordDoc.Package.Flush();
}
编辑:我发现了问题,xml 文件包含大量回车 return + 换行符。删除它们后,我可以将文件嵌入为 CustomXmlPart。
以下单元测试演示了您可以将非常大的自定义 XML 部分(在示例中最多 30MB)添加到 Word 文档:
using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using Xunit;
namespace CodeSnippets.Tests.OpenXml.Wordprocessing
{
public class LargeCustomXmlPartsTests
{
public static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
[Theory]
[InlineData(5)]
[InlineData(10)]
[InlineData(15)]
[InlineData(20)]
[InlineData(30)]
public void CanCreateLargeCustomXmlParts(int size)
{
int desiredStreamLength = size * 1024 * 1024;
string path = $"Document_{size:D2}MB.docm";
// Create a macro-enabled Word document with a custom XML part having
// at least the desired size in MB.
CreateMacroEnabledWordDocument(path, size);
// Assert that the document does have a custom XML part with at least
// the desired size.
using WordprocessingDocument wordDocument = WordprocessingDocument.Open(path, false);
CustomXmlPart customXmlPart = wordDocument.MainDocumentPart.CustomXmlParts.First();
using Stream stream = customXmlPart.GetStream(FileMode.Open, FileAccess.Read);
Assert.True(stream.Length > desiredStreamLength);
}
private static void CreateMacroEnabledWordDocument(string path, int size)
{
const WordprocessingDocumentType type = WordprocessingDocumentType.MacroEnabledDocument;
using WordprocessingDocument wordDocument = WordprocessingDocument.Create(path, type);
// Create a main document part with an empty document.
MainDocumentPart mainDocumentPart = wordDocument.AddMainDocumentPart();
WriteRootElement(mainDocumentPart,
new XElement(W + "document",
new XElement(W + "body",
new XElement(W + "p"))));
// Create a custom XML part with the desired size in MB.
CustomXmlPart customXmlPart = mainDocumentPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
WriteRootElement(customXmlPart, CreatePartRootElement(size));
}
private static void WriteRootElement(OpenXmlPart part, XElement partRootElement)
{
using Stream stream = part.GetStream(FileMode.Create, FileAccess.Write);
using XmlWriter writer = XmlWriter.Create(stream);
partRootElement.WriteTo(writer);
}
private static XElement CreatePartRootElement(int size)
{
var random = new Random();
return new XElement("root",
Enumerable.Range(0, size).Select(paragraphIndex =>
new XElement("p",
new XAttribute("i", paragraphIndex),
Enumerable.Range(0, 1000).Select(runIndex =>
new XElement("r",
new XAttribute("i", runIndex),
new XElement("t", CreateRandomString(random)))))));
}
private static string CreateRandomString(Random random)
{
char[] value = Enumerable
.Range(0, 930)
.Select(i => Convert.ToChar(random.Next(33, 125)))
.ToArray();
return new string(value);
}
}
}
在我的 Windows 10 笔记本上,Microsoft Word for Office 365 打开带有 30MB 自定义 XML 部分的文档没有任何问题。因此,我想说,您的问题一定是由其他因素或多种因素的组合引起的,包括评论中提到的 VSTO 加载项执行的自定义 XML 部分的任何处理。
我发现了问题,xml 文件包含大量回车 return + 换行符。删除它们后,我可以将文件嵌入为 CustomXmlPart。
我正在尝试将自定义xml部件添加到 docm 文件,但没有成功。 显然文件太大(超过 10mb)无法包含在包中。
如果 xml 文件大小小于 7 mb,则可以成功打开文档。
有什么想法吗?
感谢您的帮助。
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open("doc.docm", true))
{
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
if (wordDoc.MainDocumentPart.CustomXmlParts != null)
{
wordDoc.MainDocumentPart.DeleteParts<CustomXmlPart>(wordDoc.MainDocumentPart.CustomXmlParts);
}
CustomXmlPart myXmlPart = mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
using (FileStream stream = new FileStream("10mbfile.xml", FileMode.Open))
{
myXmlPart.FeedData(stream);
}
wordDoc.Package.Flush();
}
编辑:我发现了问题,xml 文件包含大量回车 return + 换行符。删除它们后,我可以将文件嵌入为 CustomXmlPart。
以下单元测试演示了您可以将非常大的自定义 XML 部分(在示例中最多 30MB)添加到 Word 文档:
using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using Xunit;
namespace CodeSnippets.Tests.OpenXml.Wordprocessing
{
public class LargeCustomXmlPartsTests
{
public static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
[Theory]
[InlineData(5)]
[InlineData(10)]
[InlineData(15)]
[InlineData(20)]
[InlineData(30)]
public void CanCreateLargeCustomXmlParts(int size)
{
int desiredStreamLength = size * 1024 * 1024;
string path = $"Document_{size:D2}MB.docm";
// Create a macro-enabled Word document with a custom XML part having
// at least the desired size in MB.
CreateMacroEnabledWordDocument(path, size);
// Assert that the document does have a custom XML part with at least
// the desired size.
using WordprocessingDocument wordDocument = WordprocessingDocument.Open(path, false);
CustomXmlPart customXmlPart = wordDocument.MainDocumentPart.CustomXmlParts.First();
using Stream stream = customXmlPart.GetStream(FileMode.Open, FileAccess.Read);
Assert.True(stream.Length > desiredStreamLength);
}
private static void CreateMacroEnabledWordDocument(string path, int size)
{
const WordprocessingDocumentType type = WordprocessingDocumentType.MacroEnabledDocument;
using WordprocessingDocument wordDocument = WordprocessingDocument.Create(path, type);
// Create a main document part with an empty document.
MainDocumentPart mainDocumentPart = wordDocument.AddMainDocumentPart();
WriteRootElement(mainDocumentPart,
new XElement(W + "document",
new XElement(W + "body",
new XElement(W + "p"))));
// Create a custom XML part with the desired size in MB.
CustomXmlPart customXmlPart = mainDocumentPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
WriteRootElement(customXmlPart, CreatePartRootElement(size));
}
private static void WriteRootElement(OpenXmlPart part, XElement partRootElement)
{
using Stream stream = part.GetStream(FileMode.Create, FileAccess.Write);
using XmlWriter writer = XmlWriter.Create(stream);
partRootElement.WriteTo(writer);
}
private static XElement CreatePartRootElement(int size)
{
var random = new Random();
return new XElement("root",
Enumerable.Range(0, size).Select(paragraphIndex =>
new XElement("p",
new XAttribute("i", paragraphIndex),
Enumerable.Range(0, 1000).Select(runIndex =>
new XElement("r",
new XAttribute("i", runIndex),
new XElement("t", CreateRandomString(random)))))));
}
private static string CreateRandomString(Random random)
{
char[] value = Enumerable
.Range(0, 930)
.Select(i => Convert.ToChar(random.Next(33, 125)))
.ToArray();
return new string(value);
}
}
}
在我的 Windows 10 笔记本上,Microsoft Word for Office 365 打开带有 30MB 自定义 XML 部分的文档没有任何问题。因此,我想说,您的问题一定是由其他因素或多种因素的组合引起的,包括评论中提到的 VSTO 加载项执行的自定义 XML 部分的任何处理。
我发现了问题,xml 文件包含大量回车 return + 换行符。删除它们后,我可以将文件嵌入为 CustomXmlPart。