| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- using Aspose.Words;
- using Aspose.Words.Loading;
- using Markdig;
- using System.Text;
- using System.Text.RegularExpressions;
- public static class WordExporter
- {
- private static readonly MarkdownPipeline MarkdownPipeline = new MarkdownPipelineBuilder()
- .UseAdvancedExtensions()
- .Build();
- public static void MarkdownToWord(string markdown, string outputPath)
- {
- if (string.IsNullOrWhiteSpace(markdown))
- throw new ArgumentException("markdown 不能为空", nameof(markdown));
- // 清理 AI 常带的 ```markdown 和 ```
- markdown = CleanMarkdown(markdown);
- // AI 返回内容有时会把表格压成一行,这里做一次轻量修复
- markdown = NormalizeSingleLineTableMarkdown(markdown);
- // Markdown -> HTML,再由 Aspose 读取 HTML 保留格式
- var htmlBody = Markdown.ToHtml(markdown, MarkdownPipeline);
- var htmlContent = BuildHtmlDocument(htmlBody);
- var htmlBytes = Encoding.UTF8.GetBytes(htmlContent);
- using var stream = new MemoryStream(htmlBytes);
- stream.Position = 0;
- var loadOptions = new LoadOptions
- {
- LoadFormat = LoadFormat.Html,
- Encoding = Encoding.UTF8
- };
- //判断路径是否存在
- var dir = Path.GetDirectoryName(outputPath);
- if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(dir))
- {
- Directory.CreateDirectory(dir);
- }
- var doc = new Document(stream, loadOptions);
- doc.Save(outputPath, SaveFormat.Docx);
- }
- private static string CleanMarkdown(string input)
- {
- input = input.Trim();
- if (input.StartsWith("```markdown", StringComparison.OrdinalIgnoreCase))
- input = input.Substring("```markdown".Length);
- if (input.StartsWith("```"))
- input = input.Substring(3);
- if (input.EndsWith("```"))
- input = input.Substring(0, input.Length - 3);
- return input.Trim();
- }
- private static string NormalizeSingleLineTableMarkdown(string markdown)
- {
- if (string.IsNullOrWhiteSpace(markdown))
- return markdown;
- // 已经是多行内容则不处理
- if (markdown.Contains('\n') || markdown.Contains('\r'))
- return markdown;
- // 仅在明显是表格时处理,避免误伤普通文本
- if (!markdown.Contains("|") || !Regex.IsMatch(markdown, @"\|\s*[-:]{3,}"))
- return markdown;
- // 把单行中的“行结束 + 下一行开始”从 "| |" 规整为换行
- var normalized = Regex.Replace(markdown, @"\|\s+\|", "|\n|");
- return normalized;
- }
- private static string BuildHtmlDocument(string body)
- {
- return $@"<!DOCTYPE html>
- <html>
- <head>
- <meta charset=""utf-8"" />
- <style>
- body {{ font-family: Calibri, 'Microsoft YaHei', sans-serif; line-height: 1.6; }}
- pre, code {{ font-family: Consolas, 'Courier New', monospace; }}
- pre {{ background: #f6f8fa; padding: 8px; border-radius: 4px; }}
- table {{ border-collapse: collapse; width: 100%; }}
- th, td {{ border: 1px solid #d0d7de; padding: 6px 8px; }}
- blockquote {{ border-left: 4px solid #d0d7de; margin: 8px 0; padding-left: 12px; color: #57606a; }}
- </style>
- </head>
- <body>
- {body}
- </body>
- </html>";
- }
- }
|