You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Excel数据导入C#数组并进行算术运算(附尝试代码)

Excel数据导入双精度数组的C#实现与优化

我有一个Excel文件,需要编写代码把其中的数据导入double[,]数组,用于后续算术运算。这是我的大学作业,但我完全不懂编程。跟着视频教程尝试写了一段C#代码,想请人帮忙看看问题或者优化方向:

public partial class Form1 : Form
{
    private double[,] excelTable;

    private int totalRows = 0;

    private int totalColumns = 0;

    public Form1()
    {
        InitializeComponent();
    }

    private void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
        try
        {
            DialogResult res = openFileDialog1.ShowDialog();

            if (res == DialogResult.OK)
            {
                ExcelPackage excelFile = new ExcelPackage(new FileInfo(openFileDialog1.FileName));

                ExcelWorksheet worksheet = excelFile.Workbook.Worksheets[1];

                totalRows = worksheet.Dimension.End.Row;
                totalColumns = worksheet.Dimension.End.Column;

                excelTable = new double[totalRows, totalColumns];

                for (int rowIndex = 1; rowIndex <= totalRows; rowIndex++)
                {
                    IEnumerable<string> row = worksheet.Cells[rowIndex, 1, rowIndex, totalColumns].Select(c => c.Value == null ? string.Empty : c.Value.ToString());
                    List<string> list = row.ToList<string>();

                    for (int i = 0; i < list.Count; i++)
                    {
                        excelTable[rowIndex - 1, i] = Convert.ToDouble(list[i].Replace('.', ','));
                    }
                }

                for (int i = 0; i < totalRows; i++)
                {
                    for (int j = 0; j < totalColumns; j++)
                    {
                        richTextBox1.Text += Convert.ToString(excelTable[i, j]);
                    }
                    richTextBox1.Text += "\n";
                }
            }
            else
            {
                throw new Exception("No file selected");
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

原代码的潜在问题

  • 硬编码替换小数点为逗号:如果系统区域设置的小数分隔符是点,或者Excel数据本身用点做分隔,会直接导致转换失败
  • 未处理非数字内容:空单元格或文本内容会让Convert.ToDouble直接抛出异常
  • RichTextBox文本拼接效率低:循环里用+=会频繁创建新字符串,数据量大时会卡顿
  • 未释放资源:ExcelPackage使用后没调用Dispose,可能导致文件被占用无法修改

修正后的代码

using OfficeOpenXml;
using System.IO;
using System.Globalization;
using System.Text;

public partial class Form1 : Form
{
    private double[,] excelTable;
    private int totalRows = 0;
    private int totalColumns = 0;

    public Form1()
    {
        InitializeComponent();
        // EPPlus 5+版本需要设置许可上下文,非商业用途用NonCommercial
        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
    }

    private void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
        try
        {
            if (openFileDialog1.ShowDialog() != DialogResult.OK)
            {
                MessageBox.Show("未选择文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // using语句自动释放ExcelPackage资源,避免文件占用
            using (ExcelPackage excelFile = new ExcelPackage(new FileInfo(openFileDialog1.FileName)))
            {
                ExcelWorksheet worksheet = excelFile.Workbook.Worksheets[1];
                if (worksheet.Dimension == null)
                {
                    MessageBox.Show("工作表为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                totalRows = worksheet.Dimension.End.Row;
                totalColumns = worksheet.Dimension.End.Column;
                excelTable = new double[totalRows, totalColumns];

                // 获取系统默认的小数分隔符,兼容不同地区数据格式
                var culture = CultureInfo.CurrentCulture;
                StringBuilder sb = new StringBuilder(); // 用StringBuilder优化文本拼接

                for (int rowIndex = 1; rowIndex <= totalRows; rowIndex++)
                {
                    for (int colIndex = 1; colIndex <= totalColumns; colIndex++)
                    {
                        var cellValue = worksheet.Cells[rowIndex, colIndex].Value;
                        // 用TryParse安全转换,非数字内容默认设为0(可按需修改)
                        if (!double.TryParse(cellValue?.ToString() ?? "", NumberStyles.Any, culture, out double num))
                        {
                            num = 0;
                        }
                        excelTable[rowIndex - 1, colIndex - 1] = num;
                        sb.Append(num.ToString(culture)).Append("\t"); // 制表符分隔列,显示更清晰
                    }
                    sb.AppendLine();
                }

                richTextBox1.Text = sb.ToString();
                MessageBox.Show("数据导入完成", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show($"导入失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

关键优化说明

  1. 资源自动释放:用using包裹ExcelPackage,无需手动调用Dispose,避免文件占用问题
  2. 区域适配:使用系统当前区域的小数分隔符,不用硬编码替换,兼容不同地区的Excel数据格式
  3. 安全转换:double.TryParse代替Convert.ToDouble,遇到非数字内容不会崩溃,可自定义默认值
  4. 性能提升:StringBuilder拼接文本,避免频繁创建字符串,大数据量下更流畅
  5. 空表判断:检查worksheet.Dimension是否为null,避免空工作表导致的异常
  6. 许可设置:适配EPPlus 5+版本的许可要求,非商业用途设置LicenseContext.NonCommercial

注意事项

  • 先在项目中安装EPPlus NuGet包:右键项目 → 管理NuGet程序包 → 搜索EPPlus并安装
  • 如果Excel包含表头,需要跳过第一行的话,把循环的rowIndex起始值改成2
  • 若需要对非数字内容做特殊处理(比如弹出提示),可修改double.TryParse后的逻辑

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:14:52