C#写入Excel文件教程:从数据导出到格式化的完整指南

C#写入数据到Excel文件

在现代数据驱动的世界中,Excel文件作为一种通用的数据存储和交换格式,在企业运营和日常工作中扮演着举足轻重的作用。无论是报表生成、数据分析还是系统集成,将应用程序中的数据准确、高效地写入Excel文件都是一个普遍且关键的需求。然而,手动操作Excel不仅效率低下,还极易引入人为错误,特别是当数据量庞大或需要频繁更新时。

本文将深入探讨如何利用C#语言,结合一个功能强大且易于使用的库,实现数据的程序化写入Excel文件。我们将从环境搭建开始,逐步讲解如何创建新的Excel文件、写入各种类型的数据、格式化单元格,以及处理现有文件。通过本文的学习,您将掌握C#操作Excel的核心技能,从而极大地提升工作效率并确保数据的一致性。


为什么选择程序化写入Excel?

C#作为.NET平台的核心语言,在文件I/O和数据处理方面拥有强大的能力。将数据程序化写入Excel,相比手动操作,具有显著的优势:

  • 自动化与效率提升: 告别繁琐的手动复制粘贴,通过代码实现数据自动导出,尤其适用于周期性报表生成或大量数据处理场景。
  • 数据一致性与准确性: 避免人工输入错误,确保数据从源系统到Excel的转换过程保持高度一致性和准确性。
  • 批量处理能力: 轻松处理成千上万行数据,几秒钟内完成手动操作可能需要数小时甚至数天的工作。
  • 集成与扩展性: 可以将Excel导出功能无缝集成到现有应用程序中,根据业务需求灵活扩展功能,例如生成图表、数据透视表等。

尽管C#提供了基础的文件操作API,但直接操作Excel的二进制格式非常复杂。因此,引入一个专业的第三方库是实现高效Excel操作的最佳实践。


准备工作与环境搭建

在开始编写代码之前,我们需要确保开发环境中已安装必要的库。本文将使用一个高效的库来简化Excel操作。

  1. 创建C#项目:
    打开Visual Studio,创建一个新的C#控制台应用程序(或您选择的任何C#项目类型)。

  2. 安装NuGet包:
    在Visual Studio中,右键点击您的项目,选择“管理NuGet程序包(Manage NuGet Packages...)”。在“浏览”选项卡中,搜索并安装以下包:

    Install-Package Spire.XLS
    

    这个命令会在您的项目中添加所有必要的引用,使您能够开始使用该库提供的功能。


核心操作:将数据写入Excel文件

现在,我们已经准备好环境,可以开始编写代码来操作Excel文件了。

创建新的Excel文件并写入数据

首先,我们将学习如何创建一个全新的Excel工作簿,并向其中写入基本数据和设置单元格格式。

using Spire.Xls;
using System.Drawing; // 用于颜色设置

public class ExcelWriter
{
    public static void CreateNewExcel()
    {
        // 1. 创建一个新的Workbook对象
        Workbook workbook = new Workbook();

        // 2. 获取第一个工作表(默认会有一个Sheet1)
        Worksheet sheet = workbook.Worksheets[0];
        sheet.Name = "销售数据"; // 设置工作表名称

        // 3. 向单元格写入文本数据
        sheet.Range["A1"].Text = "产品名称";
        sheet.Range["B1"].Text = "销售数量";
        sheet.Range["C1"].Text = "单价";
        sheet.Range["D1"].Text = "总金额";

        // 4. 向单元格写入数字数据
        sheet.Range["A2"].Text = "笔记本电脑";
        sheet.Range["B2"].NumberValue = 10;
        sheet.Range["C2"].NumberValue = 8999.00;
        sheet.Range["D2"].Formula = "=B2*C2"; // 写入公式

        sheet.Range["A3"].Text = "智能手机";
        sheet.Range["B3"].NumberValue = 25;
        sheet.Range["C3"].NumberValue = 4599.50;
        sheet.Range["D3"].Formula = "=B3*C3";

        // 5. 设置单元格格式
        // 设置表头样式
        CellStyle headerStyle = workbook.Styles.Add("headerStyle");
        headerStyle.Font.IsBold = true;
        headerStyle.KnownColor = ExcelColors.LightGreen1;
        headerStyle.HorizontalAlignment = HorizontalAlignType.Center;
        headerStyle.VerticalAlignment = VerticalAlignType.Center;
        sheet.Range["A1:D1"].Style = headerStyle;

        // 设置金额列的货币格式
        sheet.Range["C2:D3"].Style.NumberFormat = "¥#,##0.00";
        
        // 自动调整列宽以适应内容
        sheet.AutoFitColumn(1);
        sheet.AutoFitColumn(2);
        sheet.AutoFitColumn(3);
        sheet.AutoFitColumn(4);

        // 6. 保存Excel文件
        string filePath = "销售报表_新.xlsx";
        workbook.SaveToFile(filePath, ExcelVersion.Version2016);
        Console.WriteLine($"Excel文件已保存到: {Path.GetFullPath(filePath)}");

        // 7. 释放资源
        workbook.Dispose();
    }
}

代码解读:

  • 我们首先创建Workbook对象,它代表一个Excel文件。
  • Worksheet对象代表工作簿中的一个工作表。
  • Range["A1"]通过索引器访问特定单元格,可以设置其TextNumberValueFormula
  • CellStyle对象允许我们自定义字体、颜色、对齐方式等。
  • AutoFitColumn方法能自动调整列宽,使内容完全显示。
  • SaveToFile方法用于保存文件,并指定Excel版本。

从集合或数据源写入数据

在实际应用中,数据往往存储在List<T>DataTable或数据库中。该库提供了便捷的方法来批量导入这些数据。

using Spire.Xls;
using System.Data;
using System.Collections.Generic;

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int Stock { get; set; }
}

public class ExcelWriter
{
    public static void WriteDataFromCollection()
    {
        Workbook workbook = new Workbook();
        Worksheet sheet = workbook.Worksheets[0];
        sheet.Name = "产品列表";

        // 准备数据
        List<Product> products = new List<Product>
        {
            new Product { Id = 1, Name = "键盘", Price = 199.00m, Stock = 50 },
            new Product { Id = 2, Name = "鼠标", Price = 99.50m, Stock = 120 },
            new Product { Id = 3, Name = "显示器", Price = 1299.00m, Stock = 30 }
        };

        // 将List<T>数据写入Excel,并包含表头
        // 第一个参数是数据源,第二个参数表示是否包含列头,
        // 第三个和第四个参数表示从Excel的第几行第几列开始写入
        sheet.InsertCollection(products, true, 1, 1);

        // 如果是DataTable,用法类似
        DataTable dataTable = new DataTable("用户信息");
        dataTable.Columns.Add("UserID", typeof(int));
        dataTable.Columns.Add("UserName", typeof(string));
        dataTable.Columns.Add("Email", typeof(string));
        dataTable.Rows.Add(101, "张三", "zhangsan@example.com");
        dataTable.Rows.Add(102, "李四", "lisi@example.com");

        // 将DataTable数据写入Excel,从A5单元格开始
        sheet.InsertDataTable(dataTable, true, 5, 1);

        // 自动调整所有列宽
        sheet.AutoFitColumns();

        string filePath = "产品与用户数据.xlsx";
        workbook.SaveToFile(filePath, ExcelVersion.Version2016);
        Console.WriteLine($"Excel文件已保存到: {Path.GetFullPath(filePath)}");

        workbook.Dispose();
    }
}

代码解读:

  • InsertCollection方法可以直接将List<T>类型的数据导入到工作表中,极大地简化了循环写入单元格的过程。
  • InsertDataTable方法则用于将DataTable中的数据导入Excel。
  • 这两个方法都支持指定是否包含列头以及写入的起始位置。

处理现有Excel文件并追加/修改数据

有时,我们可能需要修改或向一个已存在的Excel文件追加数据,而不是创建一个新文件。

using Spire.Xls;
using System.IO;

public class ExcelWriter
{
    public static void UpdateExistingExcel()
    {
        string existingFilePath = "销售报表_新.xlsx"; // 假设这个文件已经存在

        // 检查文件是否存在
        if (!File.Exists(existingFilePath))
        {
            Console.WriteLine($"文件不存在: {Path.GetFullPath(existingFilePath)},请先运行 CreateNewExcel 方法。");
            return;
        }

        // 1. 加载现有的Workbook对象
        Workbook workbook = new Workbook();
        workbook.LoadFromFile(existingFilePath);

        // 2. 获取指定的工作表
        Worksheet sheet = workbook.Worksheets["销售数据"]; // 根据名称获取

        // 3. 追加新数据行
        int lastRow = sheet.LastRow + 1; // 获取当前数据的最后一行,然后加1作为新行的起始行
        sheet.Range[$"A{lastRow}"].Text = "无线耳机";
        sheet.Range[$"B{lastRow}"].NumberValue = 50;
        sheet.Range[$"C{lastRow}"].NumberValue = 399.00;
        sheet.Range[$"D{lastRow}"].Formula = $"=B{lastRow}*C{lastRow}";
        sheet.Range[$"C{lastRow}:D{lastRow}"].Style.NumberFormat = "¥#,##0.00"; // 重新应用格式

        // 4. 修改现有单元格数据
        sheet.Range["B2"].NumberValue = 12; // 将笔记本电脑的销售数量从10修改为12
        sheet.CalculateAllValue(); // 重新计算所有公式

        // 5. 添加超链接和注释
        sheet.Range["A" + (lastRow + 2)].Text = "访问官网";
        HyperLink hyperlink = sheet.HyperLinks.Add(sheet.Range["A" + (lastRow + 2)]);
        hyperlink.Type = HyperLinkType.Url;
        hyperlink.Address = "https://www.e-iceblue.com/";

        sheet.Range["A" + (lastRow + 3)].Text = "重要提示";
        sheet.Range["A" + (lastRow + 3)].Comment.Text = "这是关于新产品的销售提示!";
        
        // 6. 保存修改
        workbook.SaveToFile(existingFilePath, ExcelVersion.Version2016);
        Console.WriteLine($"Excel文件已更新: {Path.GetFullPath(existingFilePath)}");

        workbook.Dispose();
    }
}

代码解读:

  • workbook.LoadFromFile(existingFilePath)用于加载现有文件。
  • sheet.LastRow属性可以方便地获取当前工作表中数据所在的最后一行行号。
  • 修改单元格数据后,如果存在公式,需要调用workbook.CalculateAllValue()来重新计算所有公式的结果。
  • HyperLink对象和Comment对象可以用来添加超链接和注释。

保存Excel文件

保存文件是操作的最后一步,您可以看到在上述示例中已经多次使用。SaveToFile方法允许您指定文件路径和Excel版本。

// 保存为XLSX格式(推荐)
workbook.SaveToFile("MyReport.xlsx", ExcelVersion.Version2016);

// 保存为XLS格式(兼容旧版Excel)
// workbook.SaveToFile("MyReport.xls", ExcelVersion.Version97to2003);

进阶技巧与注意事项

  • 性能优化: 对于写入大量数据(例如数十万行)的场景,避免频繁地访问单个单元格。优先使用InsertCollectionInsertDataTable进行批量写入,或者一次性获取一个范围(sheet.Range["A1:Z10000"])并设置其值。

  • 错误处理: 文件操作可能会遇到各种问题,例如文件被占用、路径不存在等。始终使用try-catch块来捕获和处理潜在的异常,提高程序的健壮性。

    try
    {
        // Excel操作代码
        workbook.SaveToFile(filePath, ExcelVersion.Version2016);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"保存Excel文件时发生错误: {ex.Message}");
    }
    
  • 资源释放: Workbook对象和Worksheet对象会占用内存和文件句柄。为了避免内存泄漏或文件锁,务必在操作完成后调用Dispose()方法来释放资源,或者使用using语句来确保资源被正确释放。该库的Workbook类实现了IDisposable接口,因此可以使用using

    using (Workbook workbook = new Workbook())
    {
        // 所有Excel操作
        // workbook.SaveToFile(...)
    } // 在这里workbook会自动Dispose
    

总结

通过本文的详细教程,我们学习了如何使用C#结合一个高效的第三方库,将数据轻松、准确地写入Excel文件。从创建新文件、写入各种类型的数据,到格式化单元格、批量导入集合数据,再到修改现有文件,我们涵盖了C#开发者在日常工作中可能遇到的核心场景。

程序化写入Excel不仅能够显著提升数据处理的效率,还能确保数据的一致性和准确性,是现代软件开发中不可或缺的技能。现在,您已经掌握了这些基础知识,鼓励您根据自己的项目需求进行实践和扩展,例如生成更复杂的图表、处理多工作表数据等。通过自动化Excel操作,您的应用程序将变得更加强大和灵活,为用户带来更好的体验。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • """1.个性化消息: 将用户的姓名存到一个变量中,并向该用户显示一条消息。显示的消息应非常简单,如“Hello ...
    她即我命阅读 8,621评论 0 5
  • 为了让我有一个更快速、更精彩、更辉煌的成长,我将开始这段刻骨铭心的自我蜕变之旅!从今天开始,我将每天坚持阅...
    李薇帆阅读 6,089评论 0 3
  • 似乎最近一直都在路上,每次出来走的时候感受都会很不一样。 1、感恩一直遇到好心人,很幸运。在路上总是...
    时间里的花Lily阅读 5,276评论 0 2
  • 1、expected an indented block 冒号后面是要写上一定的内容的(新手容易遗忘这一点); 缩...
    庵下桃花仙阅读 3,627评论 0 1
  • 一、工具箱(多种工具共用一个快捷键的可同时按【Shift】加此快捷键选取)矩形、椭圆选框工具 【M】移动工具 【V...
    墨雅丫阅读 3,587评论 0 0