C#: 用Libreoffice实现Word文件转PDF

  论坛元老 | 2025-4-17 09:32:31 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1728|帖子 1728|积分 5184

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
现实场景中要实现Word格式转PDF格式还是比较常见的。
如果要用开源的组件,只有用Libreoffice了。
一、下载安装Libreoffice

先辈入如下链接,找到最新版本和匹配的操作系统来安装。
官网试过,下载是能下载,但安装了用不了,下面的链接是镜像。
https://mirrors.cloud.tencent.com/libreoffice/libreoffice/stable/
下面的链接可以直接下载。
LibreOffice_25.2.2_Win_x86-64

二、下面是C#的帮助类中的方法:
  1. /// <summary>
  2. /// 从网络上的Word文件,获取到pdf, 保存到临时文件。后续需要写代码删除这个临时文件,否则会占用服务器资源
  3. /// </summary>
  4. /// <param name="docUrl"></param>
  5. /// <returns></returns>
  6. public static string WordUrl2Pdf(string docUrl)
  7. {
  8.     try
  9.     {
  10.         int rand = new Random().Next(1000, 9999);
  11.         var tempWord = $"d:\\tmp\\Convert\\{rand}.docx";
  12.         var tempPdf = $"d:\\tmp\\Convert\\{rand}.pdf";
  13.         FileHelper.DownloadAndSave(docUrl, tempWord);
  14.         Word2Pdf(tempWord, tempPdf);
  15.         File.Delete(tempWord);
  16.         return tempPdf;
  17.     }
  18.     catch (Exception ex)
  19.     {
  20.         Console.WriteLine(ex.Message);
  21.         return null;
  22.     }
  23. }
  24. /// <summary>
  25. /// 将 Word 文件转换为 PDF
  26. /// </summary>
  27. /// <param name="docPath">Word 文件路径</param>
  28. /// <param name="pdfPath">输出 PDF 文件路径</param>
  29. public static void Word2Pdf(string docPath, string pdfPath)
  30. {
  31.     // 检查输入文件是否存在
  32.     if (!File.Exists(docPath))
  33.     {
  34.         throw new FileNotFoundException("输入文件不存在!", docPath);
  35.     }
  36.     // 确保输出目录存在
  37.     string outputDir = System.IO.Path.GetDirectoryName(pdfPath);
  38.     if (!Directory.Exists(outputDir))
  39.     {
  40.         Directory.CreateDirectory(outputDir);
  41.     }
  42.     // 定义 LibreOffice 路径和动态端口号
  43.     string libreOfficePath = @"d:\Program Files\LibreOffice\program\soffice.exe";
  44.     int port = GetUniquePort(); // 获取唯一端口号
  45.     // 启动 LibreOffice 实例并执行转换
  46.     Process process = new Process();
  47.     process.StartInfo.FileName = libreOfficePath;
  48.     process.StartInfo.Arguments = $"--headless --accept="socket,host=localhost,port={port};urp;" --convert-to pdf --outdir "{outputDir}" "{docPath}"";
  49.     process.StartInfo.UseShellExecute = false;
  50.     process.StartInfo.CreateNoWindow = true;
  51.     try
  52.     {
  53.         Console.WriteLine($"正在转换文件 {docPath} -> {pdfPath},使用端口: {port}");
  54.         process.Start();
  55.         process.WaitForExit();
  56.         if (process.ExitCode != 0)
  57.         {
  58.             throw new Exception($"转换失败,退出代码: {process.ExitCode}");
  59.         }
  60.     }
  61.     catch (Exception ex)
  62.     {
  63.         throw new Exception($"转换文件 {docPath} 时发生错误: {ex.Message}", ex);
  64.     }
  65.     finally
  66.     {
  67.         // 确保进程结束
  68.         if (!process.HasExited)
  69.         {
  70.             process.Kill();
  71.         }
  72.     }
  73. }
  74. /// <summary>
  75. /// 获取唯一的端口号
  76. /// </summary>
  77. /// <returns>唯一端口号</returns>
  78. private static int GetUniquePort()
  79. {
  80.     // 使用 Interlocked.Increment 确保线程安全
  81.     int basePort = 2002; // 起始端口号
  82.     return basePort + Interlocked.Increment(ref _portCounter);
  83. }
  84. private static int _portCounter = 0; // 全局计数器,用于生成唯一端口号
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表