现实场景中要实现Word格式转PDF格式还是比较常见的。
如果要用开源的组件,只有用Libreoffice了。
一、下载安装Libreoffice
先进入如下链接,找到最新版本和匹配的操作系统来安装。
官网试过,下载是能下载,但安装了用不了,下面的链接是镜像。
https://mirrors.cloud.tencent.com/libreoffice/libreoffice/stable/
下面的链接可以直接下载。
LibreOffice_25.2.2_Win_x86-64
二、下面是C#的帮助类中的方法:
/// <summary>
/// 从网络上的Word文件,获取到pdf, 保存到临时文件。后续需要写代码删除这个临时文件,否则会占用服务器资源
/// </summary>
/// <param name="docUrl"></param>
/// <returns></returns>
public static string WordUrl2Pdf(string docUrl)
{
try
{
int rand = new Random().Next(1000, 9999);
var tempWord = $"d:\\tmp\\Convert\\{rand}.docx";
var tempPdf = $"d:\\tmp\\Convert\\{rand}.pdf";
FileHelper.DownloadAndSave(docUrl, tempWord);
Word2Pdf(tempWord, tempPdf);
File.Delete(tempWord);
return tempPdf;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// 将 Word 文件转换为 PDF
/// </summary>
/// <param name="docPath">Word 文件路径</param>
/// <param name="pdfPath">输出 PDF 文件路径</param>
public static void Word2Pdf(string docPath, string pdfPath)
{
// 检查输入文件是否存在
if (!File.Exists(docPath))
{
throw new FileNotFoundException("输入文件不存在!", docPath);
}
// 确保输出目录存在
string outputDir = System.IO.Path.GetDirectoryName(pdfPath);
if (!Directory.Exists(outputDir))
{
Directory.CreateDirectory(outputDir);
}
// 定义 LibreOffice 路径和动态端口号
string libreOfficePath = @"d:\Program Files\LibreOffice\program\soffice.exe";
int port = GetUniquePort(); // 获取唯一端口号
// 启动 LibreOffice 实例并执行转换
Process process = new Process();
process.StartInfo.FileName = libreOfficePath;
process.StartInfo.Arguments = $"--headless --accept=\"socket,host=localhost,port={port};urp;\" --convert-to pdf --outdir \"{outputDir}\" \"{docPath}\"";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
try
{
Console.WriteLine($"正在转换文件 {docPath} -> {pdfPath},使用端口: {port}");
process.Start();
process.WaitForExit();
if (process.ExitCode != 0)
{
throw new Exception($"转换失败,退出代码: {process.ExitCode}");
}
}
catch (Exception ex)
{
throw new Exception($"转换文件 {docPath} 时发生错误: {ex.Message}", ex);
}
finally
{
// 确保进程结束
if (!process.HasExited)
{
process.Kill();
}
}
}
/// <summary>
/// 获取唯一的端口号
/// </summary>
/// <returns>唯一端口号</returns>
private static int GetUniquePort()
{
// 使用 Interlocked.Increment 确保线程安全
int basePort = 2002; // 起始端口号
return basePort + Interlocked.Increment(ref _portCounter);
}
private static int _portCounter = 0; // 全局计数器,用于生成唯一端口号