用 NPOI 组件实现数据导出

利用 Nuget 安装 NPOI 组件。

所需引用的 dll:ICSharpCode.SharpZipLib.dll、NPOI.dll、NPOI.OOXML.dll、NPOI.OpenXml4Net.dll、NPOI.OpenXmlFormats.dll

程序代码: 

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

namespace MyBaseFramework
{
    /// <summary>
    /// Excel 数据导入导出
    /// </summary>
    public class ExcelHelper
    {
        /// <summary>
        /// 从 Excel 导入数据
        /// </summary>
        /// <param name="fileFullPath">Excel文件路径及名称</param>
        /// <param name="sheetName">excel中的sheet名称</param>
        /// <param name="firstRowIsTitle">第一行是否是列标题</param>
        /// <returns>DataTable格式的数据</returns>
        public static DataTable ImportDataFromExcel(string fileFullPath, string sheetName = "", bool firstRowIsTitle = true)
        {
            IWorkbook workbook = null;
            ISheet sheet = null;
            DataTable dataTable = new DataTable();

            //检查文件是否存在
            if (!File.Exists(fileFullPath)) return null;

            using (FileStream fs = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read))
            {
                try
                {
                    if (fileFullPath.IndexOf(".xlsx") > 0) // Excle 2007 及以后的版本
                        workbook = new XSSFWorkbook(fs);
                    else if (fileFullPath.IndexOf(".xls") > 0) // Excle 2003 及以前的版本
                        workbook = new HSSFWorkbook(fs);


                    //如果指定了sheet名称则打开指定的sheet
                    if (!string.IsNullOrEmpty(sheetName))
                    {
                        sheet = workbook.GetSheet(sheetName);

                        if (sheet == null) return null;
                    }
                    else
                        sheet = workbook.GetSheetAt(0); //Excel中至少会存在一个Sheet

                    //处理sheet中的数据
                    IRow firstRow = sheet.GetRow(0);
                    int columnCount = firstRow.LastCellNum; //取第一行中最后一个cell的编号,即总列数
                    int rowCount = sheet.LastRowNum; //取最后一行的行号,即总行数
                    int dataRowStart = 0; //sheet中数据起始行的序号

                    //给datatable依次添加列标题
                    if (firstRowIsTitle)
                    {
                        for (int i = firstRow.FirstCellNum; i < columnCount; ++i)
                        {
                            ICell cell = firstRow.GetCell(i);
                            if (cell != null)
                            {
                                string cellValue = cell.StringCellValue;

                                //判断列标题是否为空
                                if (!string.IsNullOrEmpty(cellValue))
                                {
                                    DataColumn column = new DataColumn(cellValue);
                                    dataTable.Columns.Add(column);
                                }
                            }
                        }
                        dataRowStart = sheet.FirstRowNum + 1;
                    }
                    else
                        dataRowStart = sheet.FirstRowNum;

                    //给datatable依次添加各行数据
                    for (int i = dataRowStart; i <= rowCount; ++i)
                    {
                        IRow row = sheet.GetRow(i);
                        if (row == null)  //没有数据的行默认是null
                            continue;

                        DataRow dataRow = dataTable.NewRow();
                        for (int j = row.FirstCellNum; j < columnCount; ++j)
                        {
                            ICell cell = row.GetCell(j);

                            if (cell != null)
                            {
                                //根据格式读取数据类型
                                switch (cell.CellType)
                                {
                                    case CellType.Blank:
                                        dataRow[j] = "";
                                        break;
                                    case CellType.String:
                                        dataRow[j] = cell.StringCellValue;
                                        break;
                                    case CellType.Numeric: //数值
                                        if (DateUtil.IsCellDateFormatted(cell)) //检查单元格格式是否为日期格式
                                            dataRow[j] = cell.DateCellValue;
                                        else
                                            dataRow[j] = cell.NumericCellValue;
                                        break;
                                    case CellType.Formula: //公式
                                        HSSFFormulaEvaluator e = new HSSFFormulaEvaluator(workbook);
                                        dataRow[j] = e.Evaluate(cell).StringValue;
                                        break;
                                    default:
                                        dataRow[j] = "";
                                        break;
                                }
                            }
                        }

                        dataTable.Rows.Add(dataRow);
                    }

                    return dataTable;
                }
                catch (Exception ex)
                {
                    fs.Close();
                    throw ex;
                }
            }
        }

        /// <summary>
        /// 导出数据到 Excel
        /// </summary>
        /// <param name="dt">源数据</param>
        /// <param name="fileSaveFullPath">Excel 文件保存位置</param>
        public static void ExportDataToExcel(DataTable dt, string fileSaveFullPath)
        {
            try
            {
                IWorkbook workbook = null;
                ISheet sheet = null;

                if (fileSaveFullPath.IndexOf(".xlsx") > 0) // Excle 2007 及以后的版本
                    workbook = new XSSFWorkbook();
                else if (fileSaveFullPath.IndexOf(".xls") > 0) // Excle 2003 及以前的版本
                    workbook = new HSSFWorkbook();

                sheet = workbook.CreateSheet();

                // 表头的样式
                ICellStyle headStyle = workbook.CreateCellStyle();
                headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
                IFont font = workbook.CreateFont();
                font.FontHeightInPoints = 10;
                font.Boldweight = 700;
                headStyle.IsLocked = true;
                headStyle.SetFont(font);

                // 数据内容的样式
                IFont fontText = workbook.CreateFont();
                fontText.FontHeightInPoints = 10;
                ICellStyle styleText = workbook.CreateCellStyle();
                styleText.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
                styleText.SetFont(fontText);

                // 数据行索引
                int rowIndex = 0;

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    if (i == 0 || i % 65535 == 0)
                    {
                        // Excle 2003 及以前的版本单个 sheet 最多只支持 65535 行,超出后重新创建 sheet
                        if (i > 0) sheet = workbook.CreateSheet();

                        // 设置表头
                        IRow headerRow = sheet.CreateRow(0);
                        foreach (DataColumn column in dt.Columns)
                        {
                            int columnIndex = column.Ordinal;

                            headerRow.CreateCell(columnIndex).SetCellValue(column.Caption);
                            headerRow.GetCell(columnIndex).CellStyle = headStyle;
                            sheet.SetColumnWidth(columnIndex, 50 * 128);
                        }

                        // 固定首行
                        sheet.CreateFreezePane(0, 1, 0, dt.Columns.Count - 1);

                        rowIndex = 1;
                    }

                    // 填充数据
                    IRow dataRow = sheet.CreateRow(rowIndex);
                    foreach (DataColumn column in dt.Columns)
                    {
                        dataRow.CreateCell(column.Ordinal).SetCellValue(Convert.ToString(dt.Rows[i][column]));
                        dataRow.GetCell(column.Ordinal).CellStyle = styleText;
                    }

                    rowIndex++;
                }

                // 保存文件
                using (MemoryStream ms = new MemoryStream())
                {
                    workbook.Write(ms);

                    using (FileStream fs = new FileStream(fileSaveFullPath, FileMode.Create, FileAccess.Write))
                    {
                        byte[] data = ms.ToArray();
                        fs.Write(data, 0, data.Length);

                        fs.Flush();
                        ms.Flush();
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 从特定格式的数据字典Excel文件中提取的数据
        /// 说明:该方法用于根据数据字典文档来生成数据库表
        /// </summary>
        /// <param name="fileFullPath">Excel文件路径及名称</param>
        /// <returns></returns>
        public static List<DataTable> ImportDataFromExcelForGenDbScript(string fileFullPath)
        {
            IWorkbook workbook = null;
            ISheet sheet = null;

            try
            {
                using (FileStream fs = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read))
                {
                    if (fileFullPath.IndexOf(".xlsx") > 0) // Excle 2007 及以后的版本
                        workbook = new XSSFWorkbook(fs);
                    else if (fileFullPath.IndexOf(".xls") > 0) // Excle 2003 及以前的版本
                        workbook = new HSSFWorkbook(fs);

                    fs.Flush();
                    fs.Close();
                }

                List<DataTable> _dataDictionaryList = new List<DataTable>();
                for (int i = 0; i < workbook.NumberOfSheets; i++)
                {
                    sheet = workbook.GetSheetAt(i);

                    if (sheet != null)
                    {
                        DataTable data = new DataTable();
                        IRow firstRow = sheet.GetRow(1); //从第二行开始才是数据行
                        int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数(舍去最后一列,因为最后一列有时变成了两列)

                        for (int j = 0; j < cellCount; j++)
                        {
                            ICell cell = firstRow.GetCell(j);
                            if (cell != null)
                            {
                                string cellValue = cell.StringCellValue;
                                if (cellValue != null)
                                {
                                    DataColumn column = new DataColumn(cellValue);
                                    data.Columns.Add(column);
                                }
                            }
                        }

                        int rowCount = sheet.LastRowNum;
                        for (int k = 0; k <= rowCount; ++k)
                        {
                            IRow row = sheet.GetRow(k);
                            if (row == null) continue; //没有数据的行默认是null   
                            if (row.GetCell(row.FirstCellNum) == null) continue; //如果第一行为空则忽略此行

                            DataRow dataRow = data.NewRow();
                            for (int m = row.FirstCellNum; m < cellCount; m++)
                                if (row.GetCell(m) != null) //同理,没有数据的单元格都默认是null
                                    dataRow[m] = row.GetCell(m).ToString();

                            data.Rows.Add(dataRow);
                        }

                        if (data != null)
                            _dataDictionaryList.Add(data);
                    }
                }
                return _dataDictionaryList;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

 

posted on 2017-12-15 11:13  wangzhiliang  阅读(235)  评论(0编辑  收藏  举报

导航