我正在使用Open XML SDK在C#中创建WordprocessingDocument
,然后将它们转换为pdf。最初,我是使用Interop将文档保存为PDF格式的,但是现在这不是一个选择。我发现LibreOffice可以转换从cmd调用soffice.exe的文档,使用普通文档我得到了很好的结果。但是,当我用动态文档测试LibreOffice转换器时,该转换器崩溃了。
我复制了其中一个文档,并使用LibreOffice Writer打开了该文档,其结构错误,然后我使用Microsoft Word打开了相同的文档,其结构也很好。最后,我用Microsoft Word将其保存,并按如下所示将两个文档作为ZIP文件打开:
这是好人:
这是不好的一个:
[我注意到,当我将文档保存在Microsoft Word中时,出现了这些Open XML部分(在此问题的较早版本中称为“文件”)。当我打开以前用Microsoft Word在LibreOffice中保存的文档时,该文档又可以了。
因此,有没有一种方法可以在不打开Microsoft Word的情况下生成这些Open XML部件(在Word文档中)?
我使用以下代码(检查它是否正在创建所有文件):
using (MemoryStream mem = new MemoryStream())
{
// Create Document
using (WordprocessingDocument wordDocument =
WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document, true))
{
// Add a main document part.
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
// Create the document structure and add some text.
mainPart.Document = new Document();
Body docBody = new Body();
// Add your docx content here
CreateParagraph(docBody);
CreateStyledParagraph(docBody);
CreateTable(docBody);
CreateList(docBody);
Paragraph pImg = new Paragraph();
ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
string imgPath = "https://cdn.pixabay.com/photo/2019/11/15/05/23/dog-4627679_960_720.png";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(imgPath);
req.UseDefaultCredentials = true;
req.PreAuthenticate = true;
req.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
imagePart.FeedData(resp.GetResponseStream());
// 1500000 and 1092000 are img width and height
Run rImg = new Run(DrawingManager(mainPart.GetIdOfPart(imagePart), "PictureName", 1500000, 1092000, string.Empty));
pImg.Append(rImg);
docBody.Append(pImg);
Paragraph pLink = new Paragraph();
// For the mainpart see above
pLink.Append(HyperLinkManager("http://YourLink", "My awesome link", mainPart));
docBody.Append(pLink);
mainPart.Document.Append(docBody);
mainPart.Document.Save();
wordDocument.Close();
}
result = Convert.ToBase64String(mem.ToArray());
}
上面的代码创建具有以下结构的名为Result.docx的Word文档:
但是没有其他任何Open XML部分(例如app.xml
或styles.xml
)
您需要在以下两者之间有所作为:
WordprocessingDocument
和[]上的最低要求>根据标准,最小的WordprocessingDocument
只需要具有以下内容的主文档部分(MainDocumentPart
,document.xml
):
<w:document xmlns:w="..."> <w:body> <w:p /> </w:body> </w:document>
仅当您具有样式或编号时才需要
StyleDefinitionsPart
(styles.xml
)或NumberingDefintionsPart
(numbering.xml
)等其他部分,在这种情况下,您必须在代码中显式创建它们。
接下来,查看您的示例代码,看来您正在创建:
CreateStyledParagraph(docBody)
),必须在StyleDefinitionsPart
(styles.xml
)中定义;和CreateList(docBody)
),必须在NumberingDefinitionsPart
(numbering.xml
)中定义。但是,您的代码既不会创建StyleDefinitionsPart
也不会创建NumberingDefintionsPart
,这意味着您的文档可能不是有效的Open XML文档。
现在,Word非常宽容,并且无声地修复了各种问题,而忽略了您的Open XML标记的某些部分(例如,您可能分配给段落的样式)。
相反,根据LibreOffice的容错程度,无效的Open XML标记可能会导致崩溃。例如,如果LibreOffice在您的StyleDefinitionsPart
中找到类似于<w:pStyle w:val="MyStyleName" />
的元素时只是假设w:document
存在,然后在询问null
时不检查是否获得了StyleDefinitionsPart
引用,则可以崩溃。