使用C#+NPOI进行Excel处理,实现多个Excel文件的求和统计

一个简易的控制台程序,使用C#+NPOI进行Excel处理,实现多个Excel文件的求和统计。

前提:

  1. 待统计的Excel格式相同
  2. 统计结果表与待统计的表格格式一致

引入如下四个动态库:
1. NPOI.dll
2. NPOI.OOXML.dll
3. NPOI.OpenXml4Net.dll
4. NPOI.OpenXmlFormats.dll

csharp 复制代码
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;

namespace excelMergeCal
{
    class Program
    {
        static String BaseDIir = "d:\\docs";
        static String ResultFile = "d:\\result.xlsx";
        static int startRow = 5;
        static int endRow = 72;
        static int startColumn = 3;
        static int endColumn = 67;
        static List<CellWithPos> AllCells = new List<CellWithPos>();
        static void Main(string[] args)
        {
            Console.WriteLine("********************************************************************************");
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("* 1.将待处理的Excel放在D盘的docs文件夹下****************************************");
            Console.WriteLine("* 2.将待处理的一个文件的全部数据单元格清空后放在D盘根目录下,命名为result.xlsx *");
            Console.WriteLine("* 3.关闭打开的excel文件 ********************************************************");
            Console.WriteLine("* 4.按下回车键(Enter)开始*******************************************************");
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("********************************************************************************");
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("等待按下回车键(Enter)开始...");
            Console.ForegroundColor = ConsoleColor.White;
            Console.ReadLine();
            ReadAllExcel();
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("处理完成,按回车键(Enter)关闭.");
            Console.ReadLine();
        }
        static void ReadAllExcel()
        {
            string[] files = Directory.GetFiles(BaseDIir, "*.*", SearchOption.AllDirectories);
            foreach (string file in files)
            {
                Console.WriteLine("正在处理文件:" + file);
                if (!file.EndsWith("xlsx") && !file.EndsWith("xls"))
                {
                    Console.WriteLine("文件 " + file + " 不是xlsx/xls后缀,已忽略.....");
                    continue;
                }
                ReadExcel(file);
                // 处理每个文件
            }
            WriteResult();
        }
        static CellWithPos Get(int row, int col)
        {
            for (int i = 0; i < AllCells.Count; i++)
            {
                if (AllCells[i].row == row && AllCells[i].column == col)
                    return AllCells[i];
            }
            return null;
        }
        public static void WriteResult()
        {
            String path = ResultFile;
            string extension = System.IO.Path.GetExtension(path);
            // 第一步:读取文件流
            NPOI.SS.UserModel.IWorkbook workbook;
            using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                if (extension.Equals(".xls"))
                {
                    workbook = new HSSFWorkbook(stream);
                }
                else
                {
                    workbook = new XSSFWorkbook(stream);
                }

                #region 读取第一个sheet页面
                ISheet sheet = workbook.GetSheetAt(0);//第一个sheet页(列表)
                int rowCount = sheet.LastRowNum;
                IRow row = sheet.GetRow(0);  //读取当前行数据
                for (int i = startRow; i <= sheet.LastRowNum & i <= endRow; i++)
                {
                    row = sheet.GetRow(i);  //读取当前行数据
                    if (row == null) continue;
                    //Console.WriteLine(row.GetCell(1).ToString());
                    for (int j = startColumn; j < row.Cells.Count & j <= endColumn; j++)
                    {
                        ICell cell = row.GetCell(j);
                        CellWithPos cp = Get(i, j);
                        if (cp != null)
                        {
                            cell.SetCellValue(cp.value);
                        }
                    }
                }
                #endregion
            }
            // 第三步:写入文件流
            using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
            {
                workbook.Write(stream);
                workbook.Close();
            }
        }
        public static void ReadExcel(string path)
        {
            try
            {
                IWorkbook wk = null;
                string extension = System.IO.Path.GetExtension(path);
                FileStream fs = File.OpenRead(path);
                if (extension.Equals(".xls"))
                {
                    //把xls文件中的数据写入wk中
                    wk = new HSSFWorkbook(fs);
                }
                else
                {
                    //把xlsx文件中的数据写入wk中
                    wk = new XSSFWorkbook(fs);
                }
                fs.Close();

                int sheetCount = wk.NumberOfSheets;//获取sheet的数量
                ISheet sheet = wk.GetSheetAt(0);//第一个sheet页(列表)
                int rowCount = sheet.LastRowNum;
                IRow row = sheet.GetRow(0);  //读取当前行数据

                #region 读取第一个sheet页面
                for (int i = startRow; i <= sheet.LastRowNum & i <= endRow; i++)
                {
                    row = sheet.GetRow(i);  //读取当前行数据
                    if (row == null) continue;
                    //Console.WriteLine(row.GetCell(1).ToString());
                    for (int j = startColumn; j < row.Cells.Count & j <= endColumn; j++)
                    {
                        ICell cell = row.GetCell(j);
                        double val = 0;
                        if (cell.CellType == CellType.Formula)
                        {
                            val = cell.NumericCellValue;
                        }
                        else if (cell.CellType == CellType.Numeric)
                        {
                            val = cell.NumericCellValue;
                        }
                        else if (cell.CellType == CellType.String || cell.CellType == CellType.Blank)
                        {
                            Double.TryParse(cell.StringCellValue, out val);
                        }
                        else
                        {
                            Console.WriteLine("單元格格式錯誤:" + i + "," + j);
                            Console.WriteLine("單元格的值:" + i + "," + j + " : " + val);
                        }
                        CellWithPos cp = Get(i, j);
                        if (cp != null)
                        {
                            cp.value += val;
                        }
                        else
                        {
                            AllCells.Add(new CellWithPos() { row = i, column = j, value = val });
                        }
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }
        class CellWithPos
        {
            public int row;
            public int column;
            public double value = 0;
        }
    }
}
相关推荐
星星会笑滴23 分钟前
vue+node+Express+xlsx+emements-plus实现导入excel,并且将数据保存到数据库
vue.js·excel·express
神仙别闹27 分钟前
基于C#和Sql Server 2008实现的(WinForm)订单生成系统
开发语言·c#
向宇it10 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
九鼎科技-Leo10 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
Heaphaestus,RC11 小时前
【Unity3D】获取 GameObject 的完整层级结构
unity·c#
baivfhpwxf202312 小时前
C# 5000 转16进制 字节(激光器串口通讯生成指定格式命令)
开发语言·c#
直裾12 小时前
Scala全文单词统计
开发语言·c#·scala
开心点幸运点13 小时前
Excel——宏教程(1)
excel
ZwaterZ13 小时前
vue el-table表格点击某行触发事件&&操作栏点击和row-click冲突问题
前端·vue.js·elementui·c#·vue
ZwaterZ15 小时前
el-table-column自动生成序号&&在序号前插入图标
前端·javascript·c#·vue