最近因为需要实现导入Word文件到富文本编辑器的需求,所以打算采用OpenXml来读取文本和图片信息并组装成html输出。当然其实也可以通过调用Office的COM接口,将文档转化为HTML(类似于用Office软件打开Word文档,然后另存为HTML文件)。

在之前的文章提取Office文件(Word、PPT)中的所有图片中已经介绍过OpenXml了,这里就不重复了。所以该方法也仅支持处理.docx格式的文档。

public string Word2Html(string filePath)
{
    List<string> paragraphHtmls = new List<string>();
    using (var doc = WordprocessingDocument.Open(filePath, false))
    {
        var mainDocumentPart = doc.MainDocumentPart;

        var body = mainDocumentPart.Document.Body;
        foreach (var paragraph in body.Elements())
        {
            StringBuilder paragraphHtml = new StringBuilder();
            foreach (var run in paragraph.ChildElements.OfType<Run>())
            {
                foreach (OpenXmlElement openXmlElement in run.Elements())
                {
                    if (openXmlElement is Text text)
                    {
                        paragraphHtml.Append(text.Text);
                    }
                    else if (openXmlElement is Drawing drawing)
                    {
                        var embed = GetPicId(drawing);
                        //得到图像流
                        var part = mainDocumentPart.GetPartById(embed);
                        using (var stream = part.GetStream())
                        {
                            //图片处理
                            var imgUrl = "";
                            paragraphHtml.Append($"<img src=\"{imgUrl}\" >");
                        }
                    }
                }
            }
            if (paragraphHtml.Length > 0)
            {
                paragraphHtmls.Add(paragraphHtml.ToString());
            }
        }
    }
    return GenerateHtml(paragraphHtmls);

    string GetPicId(Drawing drawing)
    {
        DocumentFormat.OpenXml.Drawing.Graphic? graphic;
        //得到内嵌图像的ID
        if (drawing.Inline != null)
        {
            graphic = drawing.Inline.Graphic;
        }
        //得到外嵌图像的ID
        else
        {
            graphic = drawing.ChildElements[0].GetFirstChild<DocumentFormat.OpenXml.Drawing.Graphic>();
        }
        var pic = graphic.GraphicData.GetFirstChild<DocumentFormat.OpenXml.Drawing.Pictures.Picture>();
        return pic.BlipFill.Blip.Embed.Value;
    }
}
private static string GenerateHtml(List<string> list)
{
    StringBuilder builder = new StringBuilder();
    list.ForEach(d =>
                 {
                     builder = builder.Append($"<p>{d}</p>");
                 });
    return builder.ToString();
}

需要注意图片在Word中的布局选项有嵌入性和文字环绕型,所以需要特殊处理获取对应的图片Embed编码。

补充说明:对于doc文件转成Html,可以考虑使用Spire.Doc的免费版本,对于较小的文档来说完全够用了。

友情提示:免费版有篇幅限制。在加载或操作 Word 文档时,要求 Word 文档不超过 500 个段落,25 个表格。同时将 Word 文档转换为 PDF 和 XPS 格式时,仅支持转换前三页。

public string Word2Html(string filePath)
{
    var document = new Spire.Doc.Document();
    document.LoadFromFile(filePath, FileFormat.Auto);
    var htmlFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".html");
    document.SaveToFile(htmlFilePath, FileFormat.Html);
    return htmlFilePath;
}