it编程 > 编程语言 > Asp.net

C#使用ClosedXML进行读写excel操作

17人参与 2025-05-21 Asp.net

项目简介

closedxml是.net平台上的一款开源库,它使得程序员能够方便地创建、读取和修改excel文件(.xlsx格式)。无需直接与microsoft office interop进行交互, closedxml提供了一种轻量级且高性能的方式来处理excel数据,兼容.net framework及.net core。

技术分析

易用性:closedxml提供了清晰、直观的api,使得创建表格、设置样式、插入公式等操作变得简单。例如,只需几行代码就能创建一个新的工作簿并填充数据:

using (var workbook = new xlworkbook())
{
    var worksheet = workbook.worksheets.add("sample sheet");
    worksheet.cell("a1").value = "hello";
    worksheet.cell("b1").value = "world";
    workbook.saveas("helloworld.xlsx");
}

性能优化:closedxml通过内存映射文件和延迟计算策略提高了性能,这意味着直到需要时才会计算或写入数据,减少了不必要的资源消耗。

功能全面:closedxml支持处理复杂的excel功能,如图表、数据验证、条件格式化、超链接等。此外,还支持读取和写入数据表以及处理大型数据集。

版本兼容性:该库已适配.net framework 4.0+ 和 .net core,确保了跨平台的兼容性和未来发展的潜力。

社区活跃:closedxml有一个活跃的开发团队和社区,不断修复bug、添加新功能,并对用户反馈作出积极回应。

应用场景

数据报表生成:快速将数据库数据导出到excel,生成自定义模板的报表。

文件解析:用于读取现有的excel文件,提取其中的数据进行分析或导入到其他系统。

前端下载功能:配合web应用,允许用户下载自定义的excel文件。

特点

简洁api:使代码更易于编写和理解。

强大性能:避免了对office interop的依赖,提高了运行速度和内存效率。

完整性:覆盖了大部分excel的功能特性。

可扩展性:允许自定义样式和行为以满足特定需求。

跨平台支持:可以在windows、linux和macos上运行。

c#使用closedxml读写excel

首先使用nuget安装closedxml,然后在程序中添加引用closedxml.excel;

1.导出数据到excel

public void exporttoexcel(datatable dt)
{
   using (var workbook = new xlworkbook())
   {
        if (dt.tablename == "") dt.tablename = "sheet1";
        var worksheet = workbook.worksheets.add(dt.tablename);
        var header = worksheet.firstrow();
        for (int i = 0; i < dt.columns.count; ++i)
        {
            worksheet.cell(1, i + 1).value = dt.columns[i].columnname;
            worksheet.cell(1, i + 1).style.alignment.horizontal = xlalignmenthorizontalvalues.center;
            worksheet.cell(1, i + 1).style.alignment.vertical = xlalignmentverticalvalues.center;
        }
        for (int i = 0; i < dt.rows.count; ++i)
        {
            for (int j = 0; j < dt.columns.count; ++j)
            {
                worksheet.cell(i + 2, j + 1).value = dt.rows[i][j].tostring();
                worksheet.cell(i + 2, j + 1).style.alignment.horizontal = xlalignmenthorizontalvalues.center;
                worksheet.cell(i + 2, j + 1).style.alignment.vertical = xlalignmentverticalvalues.center;
             }
         }
         workbook.saveas(sfd.filename);
     }         
}

2.从excel读取数据

public datatable importexceltodatatable(string filepath)
{
   datatable dt = new datatable();
   datacolumn datacolumn=new datacolumn("columnname1");
   dt.columns.add(datacolumn);
   datacolumn=new datacolumn("columnname2");
   dt.columns.add(datacolumn);
   datacolumn=new datacolumn("columnname3");
   dt.columns.add(datacolumn);
   datacolumn=new datacolumn("columnname4");
   dt.columns.add(datacolumn);
   using (xlworkbook workbook = new xlworkbook(filepath))
   {
       ixlworksheet worksheet = workbook.worksheet(1);                  
       bool isfirstrow = true;
       foreach (var row in worksheet.rows())
       {
           if (isfirstrow)
           { 
                isfirstrow = false;
                continue;
           }
           else
           {
                dt.rows.add();
                int i = 0;
                foreach (ixlcell cell in row.cells())
                {
                     if(i>dt.columns.count-1)
                     {
                        break;
                     }
                     dt.rows[dt.rows.count - 1][i] = cell.value.tostring();
                     i++;
                }
            }
         }
   }
   return dt;
}

3.读取内容映射到datatable

using closedxml.excel;
using documentformat.openxml.office2010.excelac;
using documentformat.openxml.spreadsheet;
using system;
using system.collections.generic;
using system.data;
using system.linq;
 
public class excelreader
{
    /// <summary>
    /// 读取 excel 文件内容并返回包含多个工作表的 dictionary 列表
    /// </summary>
    /// <param name="excelfilepath">excel 文件路径</param>
    /// <param name="sheetnames">需要读取的工作表名称列表</param>
    /// <returns>工作表:工作表数据</returns>
    public dictionary<string, datatable> readexcel(string excelfilepath, list<string> sheetnames)
    {
        dictionary<string, datatable> result = new dictionary<string, datatable>();
 
        try
        {
            using (var workbook = new xlworkbook(excelfilepath))
            {
                // 遍历所有需要读取的工作表
                foreach (var sheetname in sheetnames)
                {
                    // 判断工作表是否存在
                    if (workbook.worksheets.contains(sheetname))
                    {
                        var worksheet = workbook.worksheet(sheetname);
                        datatable datatable = convertworksheettodatatable(worksheet);
                        result.add(sheetname, datatable);
                    }
                    else
                    {
                        console.writeline($"工作表 {sheetname} 不存在!");
                    }
                }
            }
        }
        catch (exception ex)
        {
            console.writeline($"读取 excel 文件时发生错误: {ex.message}");
        }
 
        return result;
    }
 
    /// <summary>
    /// 将工作表转换为 datatable
    /// </summary>
    /// <param name="worksheet">工作表</param>
    /// <returns>转换后的 datatable</returns>
    private datatable convertworksheettodatatable(ixlworksheet worksheet)
    {
        datatable datatable = new datatable();
        bool isheaderrow = true;
 
        // 遍历工作表的每一行
        foreach (var row in worksheet.rows())
        {
            if (isheaderrow)
            {
                // 第一个非空单元格是列头
                foreach (var cell in row.cells())
                {
                    datatable.columns.add(cell.value.tostring());
                }
                isheaderrow = false;
            }
            else
            {
                // 每一行对应 datatable 的一行
                datarow datarow = datatable.newrow();
                int columnindex = 0;
 
                foreach (var cell in row.cells())
                {
                    datarow[columnindex] = cell.value.tostring();
                    columnindex++;
                }
 
                datatable.rows.add(datarow);
            }
        }
 
        return datatable;
    }
}
 
public class program
{
    public static void main()
    {
        string excelfilepath = @"c:\users\mike\desktop\demo.xlsx";
        list<string> sheetnames = new list<string> { "导入", "导入2" };
 
        excelreader excelreader = new excelreader();
        var result = excelreader.readexcel(excelfilepath, sheetnames);
        foreach (var item in result)
        {
            console.writeline($"工作表:{item.key}");
            var dt = item.value;
            foreach (datarow row in dt.rows)
            {
                //打印该行的第一列、第二列、第三列的内容
                console.writeline($"{row[0]}_{row[1]}_{row[2]}");
            }
            console.writeline();
        }
    }
}

4.读取sheet名称列表

class program
{
    static void main()
    {
        string filepath = "c:\\users\\xckj\\desktop\\导入.xlsx"; // 请替换为你文件的路径
        var list = getsheetnamelist(filepath);// 获取所有工作表(sheet)名称
    }
 
    private static list<string> getsheetnamelist(string filepath)
    {
        // 打开 excel 文件
        using (var workbook = new xlworkbook(filepath))
        {
            // 获取所有工作表(sheet)名称
            list<string> sheetnames = new list<string>();
            foreach (var worksheet in workbook.worksheets)
            {
                sheetnames.add(worksheet.name);
            }
            return sheetnames;
        }
    }
}

到此这篇关于c#使用closedxml进行读写excel操作的文章就介绍到这了,更多相关c# closedxml读写excel内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

C#继承之里氏替换原则分析

05-21

Linux使用perf跟踪.NET程序的mmap泄露的流程步骤

05-20

C#中ThreadStart委托的实现

05-20

C#使用MQTTnet实现服务端与客户端的通讯的示例

05-22

C#实现访问远程硬盘的图文教程

05-19

Core i5-12400F搭配RTX 5070 Ti合理吗? 七款游戏性能测评

05-19

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论