使用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;
        }
    }
}
相关推荐
He BianGu6 小时前
笔记:TypeDescriptor和反射
c#
星河队长8 小时前
wpf界面和net web界面的相同和不同点
ui·c#
J-SL9 小时前
C#接口的一些坑
c#
符华-9 小时前
【Go】excelize库实现excel导入导出封装(四),导出时自定义某一列或多列的单元格样式
golang·excel
快快起来写代码9 小时前
poi导出值班excel
excel
吾名招财11 小时前
五、保存数据到Excel、sqlite(爬虫及数据可视化)
爬虫·sqlite·excel
lingxiao1688812 小时前
C#Modbus通信
服务器·开发语言·网络·c#
WineMonk12 小时前
ArcGIS Pro SDK (七)编辑 15 版本控制选项
arcgis·c#·gis·arcgis pro sdk
Eiceblue13 小时前
C# 验证PDF数字签名的有效性
pdf·c#·asp.net·.netcore·visual studio
天航星15 小时前
EasyExcel 单元格根据图片数量动态设置宽度
java·excel