Excel到Word到PDF转换工具

项目说明

本项目基于.NET Framework 4.0和Visual Studio 2010,实现将多个Excel文件合并到一个Word文档,并导出为PDF。

系统要求

  • .NET Framework 4.0
  • Visual Studio 2010
  • Microsoft Office 2007或更高版本(需要安装Excel和Word)

项目设置步骤

1. 创建项目

  1. 打开Visual Studio 2010
  2. 文件 → 新建 → 项目
  3. 选择"控制台应用程序"
  4. 目标框架选择".NET Framework 4.0"
  5. 输入项目名称,点击确定

2. 添加COM引用

在项目中添加以下COM组件引用:

添加引用步骤:

  1. 右键点击项目中的"引用" → “添加引用”
  2. 切换到"COM"选项卡
  3. 找到并勾选以下组件:
    • Microsoft Excel 14.0 Object Library (或其他版本)
    • Microsoft Word 14.0 Object Library (或其他版本)
  4. 点击"确定"

注意: 版本号可能因您安装的Office版本而异:

  • Office 2007: 12.0
  • Office 2010: 14.0
  • Office 2013: 15.0
  • Office 2016: 16.0

3. 设置引用属性

添加引用后,在"引用"节点中找到这两个引用:

  1. 右键点击 → 属性
  2. 将"嵌入互操作类型"设置为"False"

4. 复制代码

将提供的 ExcelToWordToPdf.cs 代码复制到项目中。

使用方法

基本使用示例

// 1. 准备Excel文件列表
List<string> excelFiles = new List<string>
{
    @"C:\数据\销售报表.xlsx",
    @"C:\数据\库存统计.xlsx",
    @"C:\数据\财务分析.xls"
};

// 2. 指定输出路径
string wordOutputPath = @"C:\输出\合并报表.docx";
string pdfOutputPath = @"C:\输出\合并报表.pdf";

// 3. 执行转换
ExcelToWordConverter converter = new ExcelToWordConverter();
converter.ConvertExcelToWordAndPdf(excelFiles, wordOutputPath, pdfOutputPath);

代码说明

主要功能
  • ConvertExcelToWordAndPdf(): 核心转换方法
    • 参数1: Excel文件路径列表
    • 参数2: Word文档输出路径
    • 参数3: PDF文档输出路径
处理流程
  1. 创建Word应用程序和新文档
  2. 创建Excel应用程序
  3. 遍历每个Excel文件:
    • 添加文件标题
    • 读取所有工作表
    • 复制工作表内容到Word
    • 保持表格格式
  4. 保存Word文档
  5. 导出为PDF格式
  6. 清理COM对象和资源

注意事项

1. 文件路径

  • 使用完整的绝对路径
  • 路径字符串前加 @ 符号避免转义问题
  • 确保目标文件夹存在

2. Office版本兼容性

  • 代码支持 .xls 和 .xlsx 格式
  • 如果使用Office 2007,将 SaveAs2 改为 SaveAs

3. 性能考虑

  • 处理大文件可能需要较长时间
  • Excel和Word应用程序设置为不可见(Visible = false)提高性能
  • 及时释放COM对象避免内存泄漏

4. 错误处理

  • 代码包含完整的异常处理
  • 检查文件是否存在
  • 输出详细的错误信息

5. 资源清理

  • 使用 Marshal.ReleaseComObject 释放COM对象
  • 调用 GC.Collect() 强制垃圾回收
  • 在 finally 块中确保资源被释放

常见问题

问题1: 提示"未能加载文件或程序集"

解决方案:

  • 检查是否正确添加了COM引用
  • 将"嵌入互操作类型"设置为False
  • 确保安装了对应版本的Office

问题2: Excel或Word进程未关闭

解决方案:

  • 确保所有COM对象都被释放
  • 检查代码中的 Marshal.ReleaseComObject 调用
  • 在任务管理器中手动结束进程

问题3: PDF导出失败

解决方案:

  • 确保Office版本支持PDF导出(2007 SP2及以上)
  • 可能需要安装"Microsoft Save as PDF 加载项"
  • 检查PDF输出路径是否有写入权限

问题4: 表格格式丢失

解决方案:

  • 使用 PasteExcelTable 方法保持格式
  • 调整参数以保留或不保留原始格式
  • 考虑使用 PasteSpecial 方法

扩展功能建议

1. 添加进度显示

public delegate void ProgressEventHandler(int current, int total, string fileName);
public event ProgressEventHandler OnProgress;

2. 批量文件夹处理

public void ConvertFolderExcelFiles(string folderPath, string wordOutputPath, string pdfOutputPath)
{
    var excelFiles = Directory.GetFiles(folderPath, "*.xls*").ToList();
    ConvertExcelToWordAndPdf(excelFiles, wordOutputPath, pdfOutputPath);
}

3. 自定义样式

  • 设置表格边框
  • 自定义标题字体和颜色
  • 添加页眉页脚

4. 添加目录

在Word文档开头自动生成目录

编译和运行

编译

  1. 按 F6 或 Ctrl+Shift+B 编译项目
  2. 检查"输出"窗口确认无错误

运行

  1. 按 F5 运行(调试模式)
  2. 或按 Ctrl+F5 运行(非调试模式)
  3. 查看控制台输出了解进度

发布

  1. 生成 → 发布
  2. 选择发布位置
  3. 确保目标机器安装了:
    • .NET Framework 4.0
    • Microsoft Office(Excel和Word)

许可证

本代码仅供学习和参考使用。

联系和支持

如有问题,请检查:

  1. Office是否正确安装
  2. COM引用是否正确添加
  3. 文件路径是否正确
  4. 是否有足够的磁盘空间

快速入门指南

第一步:在Visual Studio 2010中创建项目

  1. 打开Visual Studio 2010

  2. 创建新项目

    • 文件 → 新建 → 项目
    • 模板:Visual C# → Windows → 控制台应用程序
    • 名称:ExcelToWordToPdf
    • 位置:选择您的项目文件夹
    • 目标框架:.NET Framework 4
    • 点击"确定"
  3. 添加提供的代码文件

    • 在解决方案资源管理器中,右键点击项目
    • 添加 → 现有项
    • 选择 ExcelToWordToPdf.csExcelToWordConverterOffice2007.cs
    • 点击"添加"

第二步:添加COM引用

这是最关键的一步!

  1. 添加Excel引用

    • 右键点击"引用" → “添加引用”
    • 切换到"COM"选项卡
    • 滚动找到"Microsoft Excel XX.0 Object Library"(XX是版本号)
    • 勾选它,点击"确定"
  2. 添加Word引用

    • 再次右键点击"引用" → “添加引用”
    • COM选项卡
    • 找到"Microsoft Word XX.0 Object Library"
    • 勾选它,点击"确定"
  3. 修改引用属性(重要!)

    • 在"引用"节点中找到刚添加的两个引用
    • 右键点击"Microsoft.Office.Interop.Excel" → 属性
    • 将"嵌入互操作类型"改为"False"
    • 对"Microsoft.Office.Interop.Word"重复相同操作

第三步:修改Main方法

打开 ExcelToWordToPdf.cs 文件,找到Main方法,修改文件路径:

static void Main(string[] args)
{
    try
    {
        // 【修改这里】设置您的Excel文件路径
        List<string> excelFiles = new List<string>
        {
            @"D:\我的文档\销售数据.xlsx",
            @"D:\我的文档\库存统计.xlsx",
            @"D:\我的文档\财务报表.xls"
        };

        // 【修改这里】设置输出路径
        string wordOutputPath = @"D:\输出\合并结果.docx";
        string pdfOutputPath = @"D:\输出\合并结果.pdf";

        // 执行转换
        ExcelToWordConverter converter = new ExcelToWordConverter();
        converter.ConvertExcelToWordAndPdf(excelFiles, wordOutputPath, pdfOutputPath);

        Console.WriteLine("所有操作完成!");
    }
    catch (Exception ex)
    {
        Console.WriteLine("程序执行失败: " + ex.Message);
        Console.WriteLine(ex.StackTrace);
    }

    Console.WriteLine("按任意键退出...");
    Console.ReadKey();
}

第四步:编译和运行

  1. 编译项目

    • 按 F6 或者点击"生成" → “生成解决方案”
    • 检查输出窗口,确保没有错误
  2. 运行程序

    • 按 F5(调试模式)或 Ctrl+F5(非调试模式)
    • 观察控制台输出

Office版本选择

根据您的Office版本选择合适的类:

Office 2010或更新版本:

ExcelToWordConverter converter = new ExcelToWordConverter();

Office 2007:

ExcelToWordConverterOffice2007 converter = new ExcelToWordConverterOffice2007();

常见错误及解决方案

错误1:无法找到类型或命名空间名称"Excel"

**原因:**未添加COM引用
**解决:**按照第二步添加Excel和Word的COM引用

错误2:未能加载文件或程序集

**原因:**嵌入互操作类型设置错误
**解决:**将两个COM引用的"嵌入互操作类型"设为False

错误3:找不到文件

**原因:**Excel文件路径错误
**解决:**检查路径是否正确,使用@"路径"格式

错误4:拒绝访问

**原因:**输出目录没有写入权限
**解决:**使用有权限的目录,或以管理员身份运行

错误5:导出PDF失败

**原因:**Office 2007可能需要安装PDF插件
解决:

  • Office 2007:安装"Microsoft Save as PDF 加载项"
  • Office 2010+:自带支持,无需额外安装

测试建议

建议先用少量简单的Excel文件测试:

  1. 创建2-3个简单的Excel文件
  2. 每个文件包含少量数据
  3. 先测试基本功能是否正常
  4. 确认无误后再处理大量数据

下一步

成功运行后,您可以:

  • 修改标题样式和格式
  • 添加自定义页眉页脚
  • 批量处理文件夹中的所有Excel文件
  • 添加进度条显示

详细信息请参考 README.md 文档。

故障排除指南

编译时错误

1. “找不到类型或命名空间名称’Excel’”

错误信息:

找不到类型或命名空间名称"Excel"(是否缺少 using 指令或程序集引用?)

原因:

  • 未添加Microsoft Excel Object Library引用

解决步骤:

  1. 右键点击项目的"引用"节点
  2. 选择"添加引用"
  3. 切换到"COM"选项卡
  4. 找到并勾选"Microsoft Excel XX.0 Object Library"
  5. 点击确定

2. “找不到类型或命名空间名称’Word’”

**解决方法:**同上,添加Microsoft Word Object Library

3. “未能加载文件或程序集’Microsoft.Office.Interop.Excel’”

错误信息:

未能加载文件或程序集"Microsoft.Office.Interop.Excel, Version=XX.0.0.0, Culture=neutral, PublicKeyToken=..."或它的某一个依赖项

原因:

  • COM引用的"嵌入互操作类型"设置为True

解决步骤:

  1. 在解决方案资源管理器中展开"引用"节点
  2. 找到Microsoft.Office.Interop.Excel
  3. 右键点击 → 属性
  4. 将"嵌入互操作类型"改为"False"
  5. 对Microsoft.Office.Interop.Word重复相同操作
  6. 重新生成项目

4. “'Application’不包含’Documents’的定义”

原因:

  • Office Interop版本不匹配
  • 引用损坏

解决方法:

  1. 删除现有的Office引用
  2. 清理项目(生成 → 清理解决方案)
  3. 重新添加COM引用
  4. 重新生成

运行时错误

5. “检索 COM 类工厂中 CLSID 为 {XXX} 的组件时失败”

错误信息:

检索 COM 类工厂中 CLSID 为 {000208D5-0000-0000-C000-000000000046} 的组件时失败

原因:

  • 未安装Microsoft Office
  • Office安装损坏
  • Office组件未正确注册

解决方法:

  1. 确认已安装Microsoft Office
  2. 修复Office安装:
    • 控制面板 → 程序和功能
    • 找到Microsoft Office
    • 右键 → 更改 → 修复
  3. 如果问题持续,尝试重新安装Office

6. “System.Runtime.InteropServices.COMException”

常见情况1:文件被占用

异常来自 HRESULT:0x800A03EC

解决方法:

  • 关闭所有Excel和Word程序
  • 检查任务管理器中是否有Excel.exe或WINWORD.exe进程
  • 手动结束这些进程
  • 重新运行程序

常见情况2:文件不存在或路径错误

异常来自 HRESULT:0x800A03EC 或 0x80070003

解决方法:

  • 检查文件路径是否正确
  • 确保文件存在
  • 使用绝对路径
  • 路径中不要包含特殊字符

常见情况3:权限不足

异常来自 HRESULT:0x80030005

解决方法:

  • 以管理员身份运行程序
  • 检查文件和文件夹权限
  • 确保输出目录有写入权限

7. PDF导出失败

**错误:**导出PDF时抛出异常

Office 2007 解决方法:

  1. 确认安装了Office 2007 Service Pack 2或更高版本
  2. 下载安装"Microsoft Save as PDF 加载项"
    • 从Microsoft官网下载
    • 或搜索"2007 Microsoft Office Add-in: Microsoft Save as PDF or XPS"

Office 2010+:

  • 通常自带PDF导出功能
  • 如仍失败,尝试修复Office安装

8. “未将对象引用设置到对象的实例”

**错误位置:**访问Excel或Word对象时

可能原因:

  • Excel文件为空
  • 工作表不存在
  • 范围对象为null

解决方法:
在代码中添加更多null检查:

if (worksheet != null && worksheet.UsedRange != null)
{
    Excel.Range usedRange = worksheet.UsedRange;
    if (usedRange.Rows.Count > 0 && usedRange.Columns.Count > 0)
    {
        // 处理数据
    }
}

9. Excel或Word进程未关闭

**问题:**运行后Excel.exe或WINWORD.exe进程残留

原因:

  • COM对象未正确释放
  • 异常导致finally块未执行

解决方法:

  1. 确保代码中所有COM对象都调用了Marshal.ReleaseComObject
  2. 使用try-finally确保清理代码执行
  3. 运行后检查任务管理器
  4. 如有残留进程,手动结束

预防措施:

finally
{
    // 释放所有COM对象
    if (usedRange != null) Marshal.ReleaseComObject(usedRange);
    if (worksheet != null) Marshal.ReleaseComObject(worksheet);
    if (workbook != null)
    {
        workbook.Close(false);
        Marshal.ReleaseComObject(workbook);
    }
    if (excelApp != null)
    {
        excelApp.Quit();
        Marshal.ReleaseComObject(excelApp);
    }
    
    // 强制垃圾回收
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
}

性能问题

10. 程序运行很慢

原因:

  • 处理大文件
  • Excel/Word应用设置为可见
  • 未禁用警告

优化方法:

// 设置应用不可见
excelApp.Visible = false;
wordApp.Visible = false;

// 禁用警告和屏幕更新
excelApp.DisplayAlerts = false;
excelApp.ScreenUpdating = false;

wordApp.ScreenUpdating = false;

11. 内存占用过高

解决方法:

  • 及时释放不需要的COM对象
  • 每处理几个文件强制调用GC.Collect()
  • 分批处理大量文件

Office版本兼容性

12. Office 2007特殊问题

SaveAs2方法不存在:

  • 使用SaveAs方法代替
  • 参考ExcelToWordConverterOffice2007.cs

方法签名不同:

// Office 2007
wordDoc.SaveAs(ref path, ref format, ...);

// Office 2010+
wordDoc.SaveAs2(path, format, ...);

13. 32位/64位问题

**错误:**在64位系统上运行失败

解决方法:

  1. 在项目属性中设置平台目标
  2. 如果安装的是32位Office,设置为x86
  3. 如果安装的是64位Office,设置为x64
  4. 或设置为AnyCPU,但可能有兼容性问题

设置步骤:

  • 项目属性 → 生成
  • 平台目标 → x86(推荐,兼容性最好)

调试技巧

14. 添加详细日志

在关键位置添加Console.WriteLine:

Console.WriteLine("开始处理文件: " + excelFile);
Console.WriteLine("打开工作表: " + worksheet.Name);
Console.WriteLine("获取数据范围...");
Console.WriteLine("复制数据...");
Console.WriteLine("粘贴到Word...");

15. 使用try-catch捕获详细错误

try
{
    // 代码
}
catch (COMException comEx)
{
    Console.WriteLine("COM错误:");
    Console.WriteLine("错误代码: " + comEx.ErrorCode);
    Console.WriteLine("消息: " + comEx.Message);
    Console.WriteLine("源: " + comEx.Source);
}
catch (Exception ex)
{
    Console.WriteLine("一般错误:");
    Console.WriteLine("类型: " + ex.GetType().Name);
    Console.WriteLine("消息: " + ex.Message);
    Console.WriteLine("堆栈: " + ex.StackTrace);
}

获取帮助

如果以上方法都无法解决问题:

  1. 检查系统配置

    • .NET Framework 4.0是否已安装
    • Office版本和位数
    • 操作系统版本
  2. 创建最小测试用例

    • 使用简单的Excel文件测试
    • 只处理一个文件
    • 逐步添加功能
  3. 查看Windows事件日志

    • 运行 → eventvwr
    • Windows日志 → 应用程序
    • 查找相关错误信息
  4. 重新安装Office

    • 完全卸载
    • 清理注册表
    • 重新安装
  5. 检查防病毒软件

    • 某些防病毒软件可能阻止COM操作
    • 临时禁用测试
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

namespace ExcelToWordToPdf
{
    /// <summary>
    /// Excel到Word到PDF转换器 - Office 2007兼容版本
    /// </summary>
    public class ExcelToWordConverterOffice2007
    {
        /// <summary>
        /// 将多个Excel文件合并到Word并导出PDF (Office 2007兼容)
        /// </summary>
        public void ConvertExcelToWordAndPdf(List<string> excelFiles, string wordOutputPath, string pdfOutputPath)
        {
            Word.Application wordApp = null;
            Word.Document wordDoc = null;
            Excel.Application excelApp = null;

            try
            {
                // 创建Word应用程序
                wordApp = new Word.Application();
                wordApp.Visible = false;

                // 创建新的Word文档
                object missing = Type.Missing;
                wordDoc = wordApp.Documents.Add(ref missing, ref missing, ref missing, ref missing);

                // 创建Excel应用程序
                excelApp = new Excel.Application();
                excelApp.Visible = false;
                excelApp.DisplayAlerts = false;

                // 遍历所有Excel文件
                for (int i = 0; i < excelFiles.Count; i++)
                {
                    string excelFile = excelFiles[i];
                    
                    if (!File.Exists(excelFile))
                    {
                        Console.WriteLine("文件不存在: " + excelFile);
                        continue;
                    }

                    Console.WriteLine("正在处理: " + excelFile);

                    // 在Word中添加标题
                    object oEndOfDoc = "\\endofdoc";
                    Word.Range rng = wordDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;
                    rng.Text = "表格 " + (i + 1) + ": " + Path.GetFileNameWithoutExtension(excelFile);
                    rng.Font.Size = 14;
                    rng.Font.Bold = 1;
                    rng.InsertParagraphAfter();

                    // 打开Excel文件
                    Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(
                        excelFile, missing, missing, missing, missing,
                        missing, missing, missing, missing,
                        missing, missing, missing, missing,
                        missing, missing);

                    try
                    {
                        // 遍历所有工作表
                        foreach (Excel.Worksheet worksheet in excelWorkbook.Worksheets)
                        {
                            try
                            {
                                // 如果工作表不只一个,添加工作表名称
                                if (excelWorkbook.Worksheets.Count > 1)
                                {
                                    object oEndOfDoc2 = "\\endofdoc";
                                    Word.Range rng2 = wordDoc.Bookmarks.get_Item(ref oEndOfDoc2).Range;
                                    rng2.Text = "工作表: " + worksheet.Name;
                                    rng2.Font.Size = 12;
                                    rng2.Font.Bold = 1;
                                    rng2.InsertParagraphAfter();
                                }

                                // 获取使用的范围
                                Excel.Range usedRange = worksheet.UsedRange;
                                
                                if (usedRange != null && usedRange.Rows.Count > 0 && usedRange.Columns.Count > 0)
                                {
                                    // 复制Excel范围
                                    usedRange.Copy(missing);

                                    // 在Word中粘贴
                                    object oEndOfDoc3 = "\\endofdoc";
                                    Word.Range pasteRange = wordDoc.Bookmarks.get_Item(ref oEndOfDoc3).Range;
                                    pasteRange.PasteExcelTable(false, false, false);

                                    // 添加段落间距
                                    object oEndOfDoc4 = "\\endofdoc";
                                    Word.Range spaceRange = wordDoc.Bookmarks.get_Item(ref oEndOfDoc4).Range;
                                    spaceRange.InsertParagraphAfter();
                                }

                                Marshal.ReleaseComObject(usedRange);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("处理工作表出错: " + worksheet.Name + " - " + ex.Message);
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(worksheet);
                            }
                        }
                    }
                    finally
                    {
                        // 关闭Excel工作簿
                        excelWorkbook.Close(false, missing, missing);
                        Marshal.ReleaseComObject(excelWorkbook);
                    }

                    // 添加分页符(除了最后一个文件)
                    if (i < excelFiles.Count - 1)
                    {
                        object oEndOfDoc5 = "\\endofdoc";
                        Word.Range breakRange = wordDoc.Bookmarks.get_Item(ref oEndOfDoc5).Range;
                        object pageBreak = Word.WdBreakType.wdPageBreak;
                        breakRange.InsertBreak(ref pageBreak);
                    }
                }

                // 保存Word文档 (Office 2007使用SaveAs而不是SaveAs2)
                Console.WriteLine("正在保存Word文档...");
                object format = Word.WdSaveFormat.wdFormatDocumentDefault;
                wordDoc.SaveAs(ref wordOutputPath, ref format, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing);
                Console.WriteLine("Word文档已保存: " + wordOutputPath);

                // 导出为PDF (需要Office 2007 SP2或更高版本)
                Console.WriteLine("正在导出PDF...");
                object pdfFormat = Word.WdExportFormat.wdExportFormatPDF;
                object pdfOptimize = Word.WdExportOptimizeFor.wdExportOptimizeForPrint;
                object pdfRange = Word.WdExportRange.wdExportAllDocument;
                object pdfItem = Word.WdExportItem.wdExportDocumentContent;
                object pdfBookmarks = Word.WdExportCreateBookmarks.wdExportCreateWordBookmarks;
                
                wordDoc.ExportAsFixedFormat(
                    pdfOutputPath,
                    pdfFormat,
                    false,
                    pdfOptimize,
                    pdfRange,
                    0, 0,
                    pdfItem,
                    true, true,
                    pdfBookmarks,
                    true, true, false,
                    ref missing);
                
                Console.WriteLine("PDF已导出: " + pdfOutputPath);
                Console.WriteLine("转换完成!");
            }
            catch (Exception ex)
            {
                Console.WriteLine("发生错误: " + ex.Message);
                throw;
            }
            finally
            {
                // 清理资源
                object saveChanges = false;
                object missing = Type.Missing;

                if (wordDoc != null)
                {
                    wordDoc.Close(ref saveChanges, ref missing, ref missing);
                    Marshal.ReleaseComObject(wordDoc);
                }

                if (wordApp != null)
                {
                    wordApp.Quit(ref missing, ref missing, ref missing);
                    Marshal.ReleaseComObject(wordApp);
                }

                if (excelApp != null)
                {
                    excelApp.Quit();
                    Marshal.ReleaseComObject(excelApp);
                }

                // 强制垃圾回收
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
            }
        }
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

namespace ExcelToWordToPdf
{
    /// <summary>
    /// 将多个Excel文件合并到Word文档并导出为PDF
    /// 基于.NET Framework 4.0
    /// </summary>
    public class ExcelToWordConverter
    {
        /// <summary>
        /// 将多个Excel文件合并到一个Word文档中,并导出为PDF
        /// </summary>
        /// <param name="excelFiles">Excel文件路径列表</param>
        /// <param name="wordOutputPath">Word输出路径</param>
        /// <param name="pdfOutputPath">PDF输出路径</param>
        public void ConvertExcelToWordAndPdf(List<string> excelFiles, string wordOutputPath, string pdfOutputPath)
        {
            Word.Application wordApp = null;
            Word.Document wordDoc = null;
            Excel.Application excelApp = null;

            try
            {
                // 创建Word应用程序
                wordApp = new Word.Application();
                wordApp.Visible = false;

                // 创建新的Word文档
                wordDoc = wordApp.Documents.Add();

                // 创建Excel应用程序
                excelApp = new Excel.Application();
                excelApp.Visible = false;
                excelApp.DisplayAlerts = false;

                // 遍历所有Excel文件
                for (int i = 0; i < excelFiles.Count; i++)
                {
                    string excelFile = excelFiles[i];
                    
                    if (!File.Exists(excelFile))
                    {
                        Console.WriteLine("文件不存在: " + excelFile);
                        continue;
                    }

                    Console.WriteLine("正在处理: " + excelFile);

                    // 在Word中添加标题
                    Word.Paragraph titlePara = wordDoc.Paragraphs.Add();
                    titlePara.Range.Text = "表格 " + (i + 1) + ": " + Path.GetFileNameWithoutExtension(excelFile);
                    titlePara.Range.Font.Size = 14;
                    titlePara.Range.Font.Bold = 1;
                    titlePara.Range.InsertParagraphAfter();

                    // 打开Excel文件
                    Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(
                        excelFile,
                        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                        Type.Missing, Type.Missing);

                    try
                    {
                        // 遍历所有工作表
                        foreach (Excel.Worksheet worksheet in excelWorkbook.Worksheets)
                        {
                            try
                            {
                                // 如果工作表不只一个,添加工作表名称
                                if (excelWorkbook.Worksheets.Count > 1)
                                {
                                    Word.Paragraph sheetPara = wordDoc.Paragraphs.Add();
                                    sheetPara.Range.Text = "工作表: " + worksheet.Name;
                                    sheetPara.Range.Font.Size = 12;
                                    sheetPara.Range.Font.Bold = 1;
                                    sheetPara.Range.InsertParagraphAfter();
                                }

                                // 获取使用的范围
                                Excel.Range usedRange = worksheet.UsedRange;
                                
                                if (usedRange != null && usedRange.Rows.Count > 0 && usedRange.Columns.Count > 0)
                                {
                                    // 复制Excel范围
                                    usedRange.Copy();

                                    // 在Word中粘贴
                                    Word.Range wordRange = wordDoc.Paragraphs[wordDoc.Paragraphs.Count].Range;
                                    wordRange.PasteExcelTable(false, false, false);

                                    // 添加段落间距
                                    Word.Paragraph spacePara = wordDoc.Paragraphs.Add();
                                    spacePara.Range.InsertParagraphAfter();
                                }

                                Marshal.ReleaseComObject(usedRange);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("处理工作表出错: " + worksheet.Name + " - " + ex.Message);
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(worksheet);
                            }
                        }
                    }
                    finally
                    {
                        // 关闭Excel工作簿
                        excelWorkbook.Close(false);
                        Marshal.ReleaseComObject(excelWorkbook);
                    }

                    // 添加分页符(除了最后一个文件)
                    if (i < excelFiles.Count - 1)
                    {
                        Word.Paragraph breakPara = wordDoc.Paragraphs.Add();
                        breakPara.Range.InsertBreak(Word.WdBreakType.wdPageBreak);
                    }
                }

                // 保存Word文档
                Console.WriteLine("正在保存Word文档...");
                wordDoc.SaveAs2(wordOutputPath);
                Console.WriteLine("Word文档已保存: " + wordOutputPath);

                // 导出为PDF
                Console.WriteLine("正在导出PDF...");
                wordDoc.ExportAsFixedFormat(
                    pdfOutputPath,
                    Word.WdExportFormat.wdExportFormatPDF,
                    false,
                    Word.WdExportOptimizeFor.wdExportOptimizeForPrint,
                    Word.WdExportRange.wdExportAllDocument,
                    0, 0,
                    Word.WdExportItem.wdExportDocumentContent,
                    true, true,
                    Word.WdExportCreateBookmarks.wdExportCreateWordBookmarks,
                    true, true, false);
                
                Console.WriteLine("PDF已导出: " + pdfOutputPath);
                Console.WriteLine("转换完成!");
            }
            catch (Exception ex)
            {
                Console.WriteLine("发生错误: " + ex.Message);
                throw;
            }
            finally
            {
                // 清理资源
                if (wordDoc != null)
                {
                    wordDoc.Close(false);
                    Marshal.ReleaseComObject(wordDoc);
                }

                if (wordApp != null)
                {
                    wordApp.Quit();
                    Marshal.ReleaseComObject(wordApp);
                }

                if (excelApp != null)
                {
                    excelApp.Quit();
                    Marshal.ReleaseComObject(excelApp);
                }

                // 强制垃圾回收
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        }

        /// <summary>
        /// 主程序示例
        /// </summary>
        static void Main(string[] args)
        {
            try
            {
                // 示例:定义Excel文件路径
                List<string> excelFiles = new List<string>
                {
                    @"C:\路径\文件1.xlsx",
                    @"C:\路径\文件2.xlsx",
                    @"C:\路径\文件3.xls"
                };

                // 定义输出路径
                string wordOutputPath = @"C:\输出路径\合并结果.docx";
                string pdfOutputPath = @"C:\输出路径\合并结果.pdf";

                // 创建转换器并执行
                ExcelToWordConverter converter = new ExcelToWordConverter();
                converter.ConvertExcelToWordAndPdf(excelFiles, wordOutputPath, pdfOutputPath);

                Console.WriteLine("所有操作完成!");
            }
            catch (Exception ex)
            {
                Console.WriteLine("程序执行失败: " + ex.Message);
                Console.WriteLine(ex.StackTrace);
            }

            Console.WriteLine("按任意键退出...");
            Console.ReadKey();
        }
    }
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐