zoukankan      html  css  js  c++  java
  • 使用NOPI导入导出Excel

    使用NOPI导入导出Excel

    最近项目需要对Excel数据进行导入导出操作,决定使用NOPI插件来进行。

    至于为什么,自行百度。

    网上的Demo很多都是12年左右,只有Excel2003格式的操作,而且NOPI的版本也比较旧了。

    你可以去NOPI官网下载最新的动态链接库,我这里用到的是2.2.1,以后建议大家也demo的时候最好带上版本号。

    本文最大的优点是 兼容了2003以及2007及以上格式。

    1.导出Excel的时候这两种格式有个最大的不同就是最大行数的不同2003是65535行,2007及以上是1048576行,

    2.导入或者说读取Excel的时候使用了NOPI自带的一个工程类WorkBootFactory,通过文件流自动判断格式。

    废话不多说了,放代码了。

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;
    using NPOI.HSSF.UserModel;
    using NPOI.SS.Formula.Eval;
    using NPOI.SS.UserModel;
    using NPOI.SS.Util;
    using NPOI.XSSF.UserModel;
    
    namespace Vevisoft.Utility.NPOIExcel
    {
    
    
        public class ExcelHelper
        {
            public enum ExcelStyle 
            {
                Office2003 = 0,
                Office2007AndAbove = 1
            }
    
            #region 从datatable中将数据导出到excel
            /// <summary>
            /// 导出DataTable到流,此方法包含所有格式。
            /// 2003 最大行数为65535,2007及以上为1048576
            /// </summary>
            /// <param name="dtSource"></param>
            /// <param name="strHeaderText"></param>
            /// <param name="excellStyle"></param>
            /// <returns></returns>
            static MemoryStream ExportDt(DataTable dtSource, string strHeaderText, ExcelStyle excellStyle=ExcelStyle.Office2007AndAbove)
            {
                IWorkbook workbook = new XSSFWorkbook();
                if (excellStyle == ExcelStyle.Office2003)
                    workbook = new HSSFWorkbook();
                //
                var sheet = workbook.CreateSheet();
                //
                //
                var dateStyle = workbook.CreateCellStyle();
                var format = workbook.CreateDataFormat();
                dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");
                //取得列宽
                var arrColWidths = new int[dtSource.Columns.Count];
                foreach (DataColumn item in dtSource.Columns)
                {
                    arrColWidths[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName).Length;
                }
                for (var i = 0; i < dtSource.Rows.Count; i++)
                {
                    for (var j = 0; j < dtSource.Columns.Count; j++)
                    {
                        var intTemp = Encoding.GetEncoding(936).GetBytes(dtSource.Rows[i][j].ToString()).Length;
                        if (intTemp > arrColWidths[j])
                        {
                            arrColWidths[j] = intTemp;
                        }
                    }
                }
                var rowIndex = 0;
                var maxRows = excellStyle == ExcelStyle.Office2003 ? 65535 : 1048576;
                foreach (DataRow row in dtSource.Rows)
                {
                    #region 新建表,填充表头,填充列头,样式
    
                    if (rowIndex == maxRows || rowIndex == 0)
                    {
                        if (rowIndex != 0)
                        {
                            sheet = workbook.CreateSheet();
                        }
    
                        #region 表头及样式
    
                        {
                            var headerRow = sheet.CreateRow(0);
                            headerRow.HeightInPoints = 25;
                            headerRow.CreateCell(0).SetCellValue(strHeaderText);
    
                            var headStyle = workbook.CreateCellStyle();
                            headStyle.Alignment = HorizontalAlignment.Center;
                            var font = workbook.CreateFont();
                            font.FontHeightInPoints = 20;
                            font.Boldweight = 700;
                            headStyle.SetFont(font);
    
                            headerRow.GetCell(0).CellStyle = headStyle;
    
                            sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1));
                            //headerRow.Dispose();
                        }
    
                        #endregion
    
    
                        #region 列头及样式
    
                        {
                            var headerRow = sheet.CreateRow(1);
    
    
                            var headStyle = workbook.CreateCellStyle();
                            headStyle.Alignment = HorizontalAlignment.Center;
                            var font = workbook.CreateFont();
                            font.FontHeightInPoints = 10;
                            font.Boldweight = 700;
                            headStyle.SetFont(font);
    
    
                            foreach (DataColumn column in dtSource.Columns)
                            {
                                headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                                headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
    
                                //设置列宽
                                sheet.SetColumnWidth(column.Ordinal, (arrColWidths[column.Ordinal] + 1) * 256);
    
                            }
                            //headerRow.Dispose();
                        }
    
                        #endregion
    
                        rowIndex = 2;
                    }
    
                    #endregion
    
                    #region 填充内容
    
                    var dataRow = sheet.CreateRow(rowIndex);
                    foreach (DataColumn column in dtSource.Columns)
                    {
                        var newCell = dataRow.CreateCell(column.Ordinal);
    
                        var drValue = row[column].ToString();
    
                        switch (column.DataType.ToString())
                        {
                            case "System.String": //字符串类型
                                double result;
                                if (IsNumeric(drValue, out result))
                                {
    
                                    double.TryParse(drValue, out result);
                                    newCell.SetCellValue(result);
                                    break;
                                }
                                newCell.SetCellValue(drValue);
                                break;
    
                            case "System.DateTime": //日期类型
                                DateTime dateV;
                                DateTime.TryParse(drValue, out dateV);
                                newCell.SetCellValue(dateV);
    
                                newCell.CellStyle = dateStyle; //格式化显示
                                break;
                            case "System.Boolean": //布尔型
                                bool boolV;
                                bool.TryParse(drValue, out boolV);
                                newCell.SetCellValue(boolV);
                                break;
                            case "System.Int16": //整型
                            case "System.Int32":
                            case "System.Int64":
                            case "System.Byte":
                                int intV;
                                int.TryParse(drValue, out intV);
                                newCell.SetCellValue(intV);
                                break;
                            case "System.Decimal": //浮点型
                            case "System.Double":
                                double doubV;
                                double.TryParse(drValue, out doubV);
                                newCell.SetCellValue(doubV);
                                break;
                            case "System.DBNull": //空值处理
                                newCell.SetCellValue("");
                                break;
                            default:
                                newCell.SetCellValue("");
                                break;
                        }
    
                    }
    
                    #endregion
    
                    rowIndex++;
                }
                using (var ms = new MemoryStream())
                {
                    workbook.Write(ms);
                    ms.Flush();
                    ms.Position = 0;
    
                    //sheet.Dispose();
                    //workbook.Dispose();
    
                    return ms;
                }
            }
            /// <summary>
            /// DataTable导出到Excel文件
            /// </summary>
            /// <param name="dtSource">源DataTable</param>
            /// <param name="strHeaderText">表头文本</param>
            /// <param name="strFileName">保存位置</param>
            public static void ExportDTtoExcel2003(DataTable dtSource, string strHeaderText, string strFileName)
            {
                using (var ms = ExportDt(dtSource, strHeaderText, ExcelStyle.Office2003))
                {
                    using (var fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
                    {
                        var data = ms.ToArray();
                        fs.Write(data, 0, data.Length);
                        fs.Flush();
                    }
                }
            }
            /// <summary>
            /// DataTable导出到Excel文件,格式为2007及以上格式
            /// </summary>
            /// <param name="dtSource">源DataTable</param>
            /// <param name="strHeaderText">表头文本</param>
            /// <param name="strFileName">保存位置</param>
            public static void ExportDtToExcel(DataTable dtSource, string strHeaderText, string strFileName)
            {
                using (var ms = ExportDt(dtSource, strHeaderText))
                {
                    using (var fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
                    {
                        var data = ms.ToArray();
                        fs.Write(data, 0, data.Length);
                        fs.Flush();
                    }
                }
            }
            #endregion
            #region 从excel中将数据导出到datatable
            /// <summary>读取excel
            /// 默认第一行为标头
            /// </summary>
            /// <param name="strFileName">excel文档路径</param>
            /// <returns></returns>
            public static DataTable ImportExceltoDt(string strFileName)
            {
                IWorkbook workbook;
                using (var file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
                    workbook = WorkbookFactory.Create(file);
                var sheet = workbook.GetSheetAt(0);
                var dt = ImportDt(sheet, 0, true);
                return dt;
            }
    
            /// <summary>
            /// 读取excel
            /// </summary>
            /// <param name="strFileName">excel文件路径</param>
            /// <param name="sheetName">需要导出的sheet</param>
            /// <param name="headerRowIndex">列头所在行号,-1表示没有列头</param>
            /// <returns></returns>
            public static DataTable ImportExceltoDt(string strFileName, string sheetName, int headerRowIndex)
            {
                IWorkbook workbook;
                using (var file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
                    workbook = WorkbookFactory.Create(file);
                var sheet = workbook.GetSheet(sheetName);
                var table = ImportDt(sheet, headerRowIndex, true);
                return table;
            }
    
            /// <summary>
            /// 读取excel
            /// </summary>
            /// <param name="strFileName">excel文件路径</param>
            /// <param name="sheetIndex">需要导出的sheet序号</param>
            /// <param name="headerRowIndex">列头所在行号,-1表示没有列头</param>
            /// <returns></returns>
            public static DataTable ImportExceltoDt(string strFileName, int sheetIndex, int headerRowIndex)
            {
                IWorkbook workbook;
                using (var file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
                    workbook = WorkbookFactory.Create(file);
                ISheet sheet = workbook.GetSheetAt(sheetIndex);
                var table = ImportDt(sheet, headerRowIndex, true);
                return table;
            }
    
            /// <summary>
            /// 读取excel
            /// </summary>
            /// <param name="strFileName">excel文件路径</param>
            /// <param name="sheetName">需要导出的sheet</param>
            /// <param name="headerRowIndex">列头所在行号,-1表示没有列头</param>
            /// <param name="needHeader"></param>
            /// <returns></returns>
            public static DataTable ImportExceltoDt(string strFileName, string sheetName, int headerRowIndex, bool needHeader)
            {
                IWorkbook workbook;
                using (var file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
                    workbook = WorkbookFactory.Create(file);
                var sheet = workbook.GetSheet(sheetName);
                var table = ImportDt(sheet, headerRowIndex, needHeader);
                return table;
            }
    
            /// <summary>
            /// 读取excel
            /// </summary>
            /// <param name="strFileName">excel文件路径</param>
            /// <param name="sheetIndex">需要导出的sheet序号</param>
            /// <param name="headerRowIndex">列头所在行号,-1表示没有列头</param>
            /// <param name="needHeader"></param>
            /// <returns></returns>
            public static DataTable ImportExceltoDt(string strFileName, int sheetIndex, int headerRowIndex, bool needHeader)
            {
                IWorkbook workbook;
                using (var file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
                    workbook = WorkbookFactory.Create(file);
                var sheet = workbook.GetSheetAt(sheetIndex);
                var table = ImportDt(sheet, headerRowIndex, needHeader);
                return table;
            }
    
            /// <summary>
            /// 将制定sheet中的数据导出到datatable中
            /// </summary>
            /// <param name="sheet">需要导出的sheet</param>
            /// <param name="headerRowIndex">列头所在行号,-1表示没有列头</param>
            /// <param name="needHeader"></param>
            /// <returns></returns>
            static DataTable ImportDt(ISheet sheet, int headerRowIndex, bool needHeader)
            {
                var table = new DataTable();
                IRow headerRow;
                int cellCount;
                try
                {
                    if (headerRowIndex < 0 || !needHeader)
                    {
                        headerRow = sheet.GetRow(0);
                        cellCount = headerRow.LastCellNum;
    
                        for (int i = headerRow.FirstCellNum; i <= cellCount; i++)
                        {
                            var column = new DataColumn(Convert.ToString(i));
                            table.Columns.Add(column);
                        }
                    }
                    else
                    {
                        headerRow = sheet.GetRow(headerRowIndex);
                        cellCount = headerRow.LastCellNum;
    
                        for (int i = headerRow.FirstCellNum; i <= cellCount; i++)
                        {
                            if (headerRow.GetCell(i) == null)
                            {
                                if (table.Columns.IndexOf(Convert.ToString(i)) > 0)
                                {
                                    var column = new DataColumn(Convert.ToString("重复列名" + i));
                                    table.Columns.Add(column);
                                }
                                else
                                {
                                    var column = new DataColumn(Convert.ToString(i));
                                    table.Columns.Add(column);
                                }
    
                            }
                            else if (table.Columns.IndexOf(headerRow.GetCell(i).ToString()) > 0)
                            {
                                var column = new DataColumn(Convert.ToString("重复列名" + i));
                                table.Columns.Add(column);
                            }
                            else
                            {
                                var column = new DataColumn(headerRow.GetCell(i).ToString());
                                table.Columns.Add(column);
                            }
                        }
                    }
                    //var rowCount = sheet.LastRowNum;
                    for (var i = (headerRowIndex + 1); i <= sheet.LastRowNum; i++)
                    {
                        try
                        {
                            IRow row;
                            row = sheet.GetRow(i) ?? sheet.CreateRow(i);
    
                            var dataRow = table.NewRow();
    
                            for (int j = row.FirstCellNum; j <= cellCount; j++)
                            {
                                try
                                {
                                    if (row.GetCell(j) != null)
                                    {
                                        switch (row.GetCell(j).CellType)
                                        {
                                            case CellType.String:
                                                var str = row.GetCell(j).StringCellValue;
                                                dataRow[j] = !string.IsNullOrEmpty(str) ? str : null;
                                                break;
                                            case CellType.Numeric:
                                                if (DateUtil.IsCellDateFormatted(row.GetCell(j)))
                                                    dataRow[j] = DateTime.FromOADate(row.GetCell(j).NumericCellValue);
                                                else
                                                    dataRow[j] = Convert.ToDouble(row.GetCell(j).NumericCellValue);
                                                break;
                                            case CellType.Boolean:
                                                dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue);
                                                break;
                                            case CellType.Error:
                                                dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue);
                                                break;
                                            case CellType.Formula:
                                                switch (row.GetCell(j).CachedFormulaResultType)
                                                {
                                                    case CellType.String:
                                                        var strFormula = row.GetCell(j).StringCellValue;
                                                        dataRow[j] = !string.IsNullOrEmpty(strFormula)
                                                            ? strFormula
                                                            : null;
                                                        break;
                                                    case CellType.Numeric:
                                                        dataRow[j] = Convert.ToString(row.GetCell(j).NumericCellValue);
                                                        break;
                                                    case CellType.Boolean:
                                                        dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue);
                                                        break;
                                                    case CellType.Error:
                                                        dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue);
                                                        break;
                                                    default:
                                                        dataRow[j] = "";
                                                        break;
                                                }
                                                break;
                                            default:
                                                dataRow[j] = "";
                                                break;
                                        }
                                    }
                                }
                                catch
                                {
                                    //wl.WriteLogs(exception.ToString());
                                }
                            }
                            table.Rows.Add(dataRow);
                        }
                        catch (Exception exception)
                        {
                            //wl.WriteLogs(exception.ToString());
                        }
                    }
                }
                catch (Exception exception)
                {
                    //wl.WriteLogs(exception.ToString());
                }
                return table;
            }
            #endregion
            #region Public Methodes
            public static bool IsNumeric(String message, out double result)
            {
                var rex = new Regex(@"^[-]?d+[.]?d*$");
                result = -1;
                if (rex.IsMatch(message))
                {
                    result = double.Parse(message);
                    return true;
                }
                return false;
            }
            /// <summary>
            /// 获取Sheet个数
            /// </summary>
            /// <param name="outputFile"></param>
            /// <returns></returns>
            public static int GetSheetCount(string outputFile)
            {
                var count = 0;
                try
                {
                    var readfile = new FileStream(outputFile, FileMode.Open, FileAccess.Read);
                    var workbook = WorkbookFactory.Create(readfile);
                    count = workbook.NumberOfSheets;
    
                }
                catch (Exception exception)
                {
                    //wl.WriteLogs(exception.ToString());
                }
                return count;
            }
            /// <summary>
            /// 获取Sheet名称列表
            /// </summary>
            /// <param name="outputFile"></param>
            /// <returns></returns>
            public static IList<string> GetSheetNames(string outputFile)
            {
                IList<string> sheetNameList = new List<string>();
                try
                {
                    var readfile = new FileStream(outputFile, FileMode.Open, FileAccess.Read);
                    var workbook = WorkbookFactory.Create(readfile);
                    for (var i = 0; i < workbook.NumberOfSheets; i++)
                        sheetNameList.Add(workbook.GetSheetName(i));
                }
                catch (Exception exception)
                {
                    //wl.WriteLogs(exception.ToString());
                }
                return sheetNameList;
            }
            #endregion
        }
    }
    

      

  • 相关阅读:
    MaltReport2:通用文档生成引擎
    PostgreSQL 10 如何使用 PgAdmin3
    Stackoverflow 珠玑:C#封装重试指定次数的功能
    C# 6 元组应用 Part 2:C# 也玩模式匹配
    C# 6 元组应用 Part 1:方便的字典工厂方法
    Stackoverflow 珠玑:用于分组的 LINQ 扩展方法
    Linux 下的 PostgreSQL 数据库+文件通用自动备份脚本
    让 Odoo POS 支持廉价小票打印机
    NopCommerce 根据手机浏览器和桌面浏览器切换 Theme
    为什么 C# 比 C++ 编译快那么多
  • 原文地址:https://www.cnblogs.com/vevi/p/5715478.html
Copyright © 2011-2022 走看看