为有中文需求的客户提供多渠道中文技术支持.

Thu Jan 16, 2025 8:56 am

使用下面代码可以将md文件转为docx文件, 但是md文件内的链接图片没有处理,显示为X, 有相关的参数可以直接处理这些链接图片吗?

在最后面的代码, 但是使用了第三方的Markdig组件, 先转为了html, 然后从html转成了docx, 最终的文档中包含了md中的图片,
有更简单的方法吗? 谢谢!

Code: Select all
using Spire.Doc;
using Spire.Doc.Documents;

// 创建一个Document类对象
Document doc = new Document();

// 加载Markdown文件
doc.LoadFromFile(@"C:\Users\Administrator\Desktop\MD\doc.md", FileFormat.Markdown);

// 将Markdown文件转换为Word文档
doc.SaveToFile(@"C:\Users\Administrator\Desktop\MD\Html2Word0.docx", FileFormat.Docx);
doc.Close();


使用了第三方组件 Markdig
Code: Select all
using Markdig;
using Spire.Doc;
using Spire.Doc.Documents;

// 读取Markdown文件
string markdown = File.ReadAllText(@"C:\Users\Administrator\Desktop\MD\doc.md");

// 将Markdown转换为HTML
string html = Markdown.ToHtml(markdown);

// 将HTML内容保存到文件
File.WriteAllText("_Temp.html", html);
Console.WriteLine("转换完成!");


//创建 Document 对象
Document document = new Document();

//从磁盘加载 HTML 文件
document.LoadFromFile("_Temp.html", FileFormat.Html, XHTMLValidationType.None);

//将 HTML 文件转为 Word 并保存
String result = @"C:\Users\Administrator\Desktop\MD\Html2Word.docx";
document.SaveToFile(result, FileFormat.Docx2013);

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Thu Jan 16, 2025 9:26 am

Hello,

你好,我们目前转这种url图片,结果的确未下载图片,这个问题我以编号SPIREDOC-11072记录到了我们系统中,我们研发将进一步调查支持。一旦有支持版本,我们会通知您。感谢你的理解。

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1510
Joined: Wed Apr 25, 2018 3:20 am

Thu Jan 16, 2025 9:41 am

Lisa.Li wrote:Hello,

你好,我们目前转这种url图片,结果的确未下载图片,这个问题我以编号SPIREDOC-11072记录到了我们系统中,我们研发将进一步调查支持。一旦有支持版本,我们会通知您。感谢你的理解。

Sincerely,
Lisa
E-iceblue support team


感谢您的回复!
我还有一个功能请求, 就是在转md文档时, 能添加一个预先设置的格式选项, 如: mdOptions,
这样就可以给md文档的各个元素设置格式了, 例如下面:
# 一级标题 设置格式: 居中, 一号字
## 二级标题 设置格式: 黑体, 二号字
等各种格式设置

另外, 在当前没有该功能的情况下, 怎样设置这些格式呢, 能提供一个简单的示例吗? 谢谢

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Thu Jan 16, 2025 9:58 am

Hello,

你好,你设置格式需求是想在docx 文档转markdown 格式的时候吗?目前我们还没有此功能,为了能准确地实现你的需求,你可以给我们具体提供个输入文档和期望的输出效果,我们研发这边去作为新功能实现。

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1510
Joined: Wed Apr 25, 2018 3:20 am

Thu Jan 16, 2025 10:26 am

Lisa.Li wrote:Hello,

你好,你设置格式需求是想在docx 文档转markdown 格式的时候吗?目前我们还没有此功能,为了能准确地实现你的需求,你可以给我们具体提供个输入文档和期望的输出效果,我们研发这边去作为新功能实现。

Sincerely,
Lisa
E-iceblue support team


您好, 需求是在 markdown 文档转docx格式的时候, 如果没有格式选项, 后期要手动做太多的格式设置就太麻烦了.
下面附件有原始md文件和最终的docx格式效果

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Fri Jan 17, 2025 6:39 am

Hello,

你好,感谢你提供更详细的信息参考,我们目前还没有接口针对markdown 转docx过程中直接对不同标题层级设置样式。但是我们产品可以添加样式,修改样式等,针对你的需求实现也比较方便。如下示例代码
Code: Select all
            Document doc = new Document();
            //doc = new Document(@"Doc.md");
            doc = new Document(@"input.docx");
            ReplaeImgPara(doc);
            //设置图片段落样式
            ParagraphStyle style = new ParagraphStyle(doc);
            style.Name = "ImgParaStyle";
            style.CharacterFormat.FontName = "楷体";
            style.CharacterFormat.FontSize = 12;
            style.ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center;
            doc.Styles.Add(style);

            foreach (Spire.Doc.Section section in doc.Sections)
            {
                //遍历段落
                for (int i=0; i< section.Paragraphs.Count; i++)
                    //foreach (Paragraph paragraph in section.Paragraphs)
                {
                    Paragraph paragraph = section.Paragraphs[i];
               
                    //判断段落样式
                    if (paragraph.StyleName == "Heading1")
                    {
                        paragraph.GetStyle().CharacterFormat.FontName = "雅黑";
                        paragraph.GetStyle().CharacterFormat.FontSize= 24;
                        paragraph.GetStyle().CharacterFormat.TextColor = Color.Blue;
                        paragraph.GetStyle().ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center; 
                    }
                    if (paragraph.StyleName == "Heading2")
                    {
                        paragraph.GetStyle().CharacterFormat.FontName = "黑体";
                        paragraph.GetStyle().CharacterFormat.FontSize = 18;
                        paragraph.GetStyle().CharacterFormat.TextColor = Color.Red;
                        paragraph.GetStyle().CharacterFormat.Italic = false;
                        paragraph.GetStyle().ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Left;
                    }
                    if (paragraph.StyleName == "Normal" && HasImg(paragraph))
                    {
                        paragraph.ApplyStyle("ImgParaStyle");
                    }
                    if (paragraph.StyleName == "Normal" && !HasImg(paragraph))
                    {
                        paragraph.GetStyle().CharacterFormat.FontName = "楷体";
                        paragraph.GetStyle().CharacterFormat.FontSize = 12;
                        paragraph.GetStyle().ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Left;
                    }

                }
            }
            doc.SaveToFile(@"out.docx", FileFormat.Docx2016);


        }

        static bool HasImg(Paragraph paragraph)
        {
            //判断段落内容是否是图片
            for (int m = 0; m < paragraph.ChildObjects.Count; m++)
            {
                DocumentObject docObj = paragraph.ChildObjects[m];
                if (docObj.DocumentObjectType == DocumentObjectType.Picture)
                {
                    return true;
                }
            }
            return false;
        }

        static void ReplaeImgPara(Document doc)
        {
            foreach (Spire.Doc.Section section in doc.Sections)
            {
                //遍历段落
                for (int i = 0; i < section.Paragraphs.Count; i++)
                {
                    Paragraph paragraph = section.Paragraphs[i];
                    for (int m = 0; m < paragraph.ChildObjects.Count; m++)
                    {
                        DocumentObject docObj = paragraph.ChildObjects[m];
                        if (docObj.DocumentObjectType == DocumentObjectType.Picture)
                        {
                            //图片单独添加到段落中
                            Spire.Doc.Documents.Paragraph para = new Spire.Doc.Documents.Paragraph(doc);
                            DocPicture picture = (DocPicture)docObj;
                            picture.TextWrappingStyle = TextWrappingStyle.Inline;
                            para.ChildObjects.Insert(0, picture);
                            section.Paragraphs.Insert(i, para);
                            paragraph.ChildObjects.Remove(docObj);
                        }
                    }
                }
            }
        }

因目前.md 文件url 图片转换还有显示问题,我这里先直接将你.md 文件转换到docx 格式作为输入测试文档。后期待SPIREDOC-11072修复后,就可以直接加载原始.md 文件。

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1510
Joined: Wed Apr 25, 2018 3:20 am

Fri Jan 17, 2025 11:45 am

Lisa.Li wrote:Hello,

你好,感谢你提供更详细的信息参考,我们目前还没有接口针对markdown 转docx过程中直接对不同标题层级设置样式。但是我们产品可以添加样式,修改样式等,针对你的需求实现也比较方便。如下示例代码
Code: Select all
            Document doc = new Document();
            //doc = new Document(@"Doc.md");
            doc = new Document(@"input.docx");
            ReplaeImgPara(doc);
            //设置图片段落样式
            ParagraphStyle style = new ParagraphStyle(doc);
            style.Name = "ImgParaStyle";
            style.CharacterFormat.FontName = "楷体";
            style.CharacterFormat.FontSize = 12;
            style.ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center;
            doc.Styles.Add(style);

            foreach (Spire.Doc.Section section in doc.Sections)
            {
                //遍历段落
                for (int i=0; i< section.Paragraphs.Count; i++)
                    //foreach (Paragraph paragraph in section.Paragraphs)
                {
                    Paragraph paragraph = section.Paragraphs[i];
               
                    //判断段落样式
                    if (paragraph.StyleName == "Heading1")
                    {
                        paragraph.GetStyle().CharacterFormat.FontName = "雅黑";
                        paragraph.GetStyle().CharacterFormat.FontSize= 24;
                        paragraph.GetStyle().CharacterFormat.TextColor = Color.Blue;
                        paragraph.GetStyle().ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center; 
                    }
                    if (paragraph.StyleName == "Heading2")
                    {
                        paragraph.GetStyle().CharacterFormat.FontName = "黑体";
                        paragraph.GetStyle().CharacterFormat.FontSize = 18;
                        paragraph.GetStyle().CharacterFormat.TextColor = Color.Red;
                        paragraph.GetStyle().CharacterFormat.Italic = false;
                        paragraph.GetStyle().ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Left;
                    }
                    if (paragraph.StyleName == "Normal" && HasImg(paragraph))
                    {
                        paragraph.ApplyStyle("ImgParaStyle");
                    }
                    if (paragraph.StyleName == "Normal" && !HasImg(paragraph))
                    {
                        paragraph.GetStyle().CharacterFormat.FontName = "楷体";
                        paragraph.GetStyle().CharacterFormat.FontSize = 12;
                        paragraph.GetStyle().ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Left;
                    }

                }
            }
            doc.SaveToFile(@"out.docx", FileFormat.Docx2016);


        }

        static bool HasImg(Paragraph paragraph)
        {
            //判断段落内容是否是图片
            for (int m = 0; m < paragraph.ChildObjects.Count; m++)
            {
                DocumentObject docObj = paragraph.ChildObjects[m];
                if (docObj.DocumentObjectType == DocumentObjectType.Picture)
                {
                    return true;
                }
            }
            return false;
        }

        static void ReplaeImgPara(Document doc)
        {
            foreach (Spire.Doc.Section section in doc.Sections)
            {
                //遍历段落
                for (int i = 0; i < section.Paragraphs.Count; i++)
                {
                    Paragraph paragraph = section.Paragraphs[i];
                    for (int m = 0; m < paragraph.ChildObjects.Count; m++)
                    {
                        DocumentObject docObj = paragraph.ChildObjects[m];
                        if (docObj.DocumentObjectType == DocumentObjectType.Picture)
                        {
                            //图片单独添加到段落中
                            Spire.Doc.Documents.Paragraph para = new Spire.Doc.Documents.Paragraph(doc);
                            DocPicture picture = (DocPicture)docObj;
                            picture.TextWrappingStyle = TextWrappingStyle.Inline;
                            para.ChildObjects.Insert(0, picture);
                            section.Paragraphs.Insert(i, para);
                            paragraph.ChildObjects.Remove(docObj);
                        }
                    }
                }
            }
        }

因目前.md 文件url 图片转换还有显示问题,我这里先直接将你.md 文件转换到docx 格式作为输入测试文档。后期待SPIREDOC-11072修复后,就可以直接加载原始.md 文件。

Sincerely,
Lisa
E-iceblue support team


感谢, 看了一下效果, 不错!
但是, 强烈建议后期能直接对不同标题层级进行预设置的样式, 因为md的构成对象相比word要很少很多, 也简单很多, 预设格式选项, 实现起来要优雅多了, 已经有组件支持这种方式(在转换前预设置格式),

下面内容供参考, 能对下面几类对象进行格式预设就够用了,不复杂:
markdown结构对象包括以下几类:
1. 标题 (Headers)
使用 # 来表示不同级别的标题。共6个级别(从 # 到 ######)。

2. 正文段落 (Paragraphs)
多个段落之间用空行隔开。

3. 列表 (Lists)
无序列表 (Unordered List):使用 *、+ 或 - 来创建。
有序列表 (Ordered List):使用数字加点 1.、2. 等来创建。

4. 代码 (Code)
内联代码 (Inline Code):使用反引号 ` 包裹。
代码块 (Code Block):使用三个反引号 ```,也可以指定语言来进行语法高亮。

5. 图片 (Images)

6. 表格 (Tables)

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Mon Jan 20, 2025 10:27 am

Hello,

你好,
感谢你的反馈,你这个需求我这边以编号SPIREDOC-11073 记录提交到了我们研发团队,他们后期将进一步调查实现的方式。后期有任何更新,我们会同步通知到您。另外,你提到的已经实现的组件,是否能分享下他的实现接口方式参考?如果不方便也没有关系。

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1510
Joined: Wed Apr 25, 2018 3:20 am

Tue Jan 21, 2025 11:29 am

Lisa.Li wrote:Hello,

你好,
感谢你的反馈,你这个需求我这边以编号SPIREDOC-11073 记录提交到了我们研发团队,他们后期将进一步调查实现的方式。后期有任何更新,我们会同步通知到您。另外,你提到的已经实现的组件,是否能分享下他的实现接口方式参考?如果不方便也没有关系。

Sincerely,
Lisa
E-iceblue support team


我用的最多的是Pandoc, 有我提到的实现方式

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Wed Jan 22, 2025 1:59 am

Hello,

你好,非常感谢你的分享,我了解了使用此工具在转markdown到docx指定样式的应用,我一并提交给我们研发参考了。 他们将结合我们产品底层一些逻辑进一步具体调查看如何实现这个功能,后期版本上线了,我们会通知到您。

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1510
Joined: Wed Apr 25, 2018 3:20 am

Wed Jan 22, 2025 6:27 am

Lisa.Li wrote:Hello,

你好,非常感谢你的分享,我了解了使用此工具在转markdown到docx指定样式的应用,我一并提交给我们研发参考了。 他们将结合我们产品底层一些逻辑进一步具体调查看如何实现这个功能,后期版本上线了,我们会通知到您。


谢谢, 期待能早日实现, 该功能太实用了!

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Thu Mar 20, 2025 4:05 am

Hello,

你好,我们最新版本 Spire.Doc Pack(hot fix)版本: 13.3.6针对SPIREDOC-11072 markdown 转docx, url 图片不显示的问题进行了调整处理,请知悉并更新测试。针对SPIREDOC-11073的优化任务还在进行中,待有相应优化版本时,我们会告知您。
Website link: https://www.e-iceblue.cn/Downloads/Spire-Doc-NET.html
Nuget link:https://www.nuget.org/packages/Spire.Doc

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1510
Joined: Wed Apr 25, 2018 3:20 am

Fri Jun 13, 2025 11:25 am

Lisa.Li wrote:Hello,

你好,我们最新版本 Spire.Doc Pack(hot fix)版本: 13.3.6针对SPIREDOC-11072 markdown 转docx, url 图片不显示的问题进行了调整处理,请知悉并更新测试。针对SPIREDOC-11073的优化任务还在进行中,待有相应优化版本时,我们会告知您。
Website link: https://www.e-iceblue.cn/Downloads/Spire-Doc-NET.html
Nuget link:https://www.nuget.org/packages/Spire.Doc

Sincerely,
Lisa
E-iceblue support team


关于 SPIREDOC-11073的优化任务 有进展吗? 该功能在ai问答都是md格式的时代的使用频率确实非常高, 期待早日实现!

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Mon Jun 16, 2025 10:26 am

你好,

感谢你的反馈,针对SPIREDOC-11073的优化,目前还在处理完善中,我们也很重视这个功能的进一步完善和优化。一旦有可用的更新版本。我会及时反馈给你。

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1510
Joined: Wed Apr 25, 2018 3:20 am

Tue Jun 17, 2025 7:00 am

你好,

针对SPIREDOC-11073,就转md 到word 时应用预设置样式的支持,目前我们内部的实现类似你前面提到的Pandoc工具,在保存到word 之前,通过从传入有预设置样式的word模板文档复制相应样式进行应用,然后保存。这种就是预设置样式在模板word 文档里面就设置好,如果预设置样式是txt 文本格式我们在获取文本内容再去解析,相对没有直接从模板文件中读取的数据完整。你确认下目前用word 模板方式这种预设置样式针对你们实际场景是否便捷呢?期待你的反馈。

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1510
Joined: Wed Apr 25, 2018 3:20 am

Return to 中文技术支持