NPOI通过DataTable导出和读取Excel

Excel导入及导出问题产生:


  从接触.net到现在一直在维护一个DataTable导出到Excel的类,时不时还会维护一个导入类。以下是时不时就会出现的问题:

导出问题:

  如果是asp.net,你得在服务器端装Office,几百M呢,还得及时更新它,以防漏洞,还得设定权限允许ASP.net访问COM+,听说如果导出过程中出问题可能导致服务器宕机。

  Excel会把只包含数字的列进行类型转换,本来是文本型的,它非要把你转成数值型的,像身份证后三位变成000,编号000123会变成123,够智能吧,够郁闷吧。不过这些都还是可以变通解决的,在他们前边加上一个字母,让他们不只包含数字。

  导出时,如果你的字段内容以"-"或"="开头,Excel好像把它当成了公式什么的,接下来就出错,提示:类似,保存到Sheet1的问题

导入问题:

  Excel会根据你的 Excel文件前8行分析数据类型,如果正好你前8行某一列只是数字,那它会认为你这一列就是数值型的,然后,身份证,手机,编号都转吧变成类似这样的 1.42702E+17格式,日期列变成 包含日期和数字的,乱的很,可以通过改注册表让Excel分析整个表,但如果整列都是数字,那这个问题还是解决不了。


  以上问题,一般人初次做时肯定得上网查查吧,一个问题接着另一个问题,查到你郁郁而死,还有很多问题没解决,最终感觉已经解决的不错了,但还不能保证某一天还会出个什么问题。

使用第三方开源组件导入及导出Excel的解决方案:


  偶然间发现了NPOI与MyXls,相见恨晚,害的我在Excel上浪费了那么多时间,他们俩的好处是:就是.net的自定义类库,可以直 接对Excel进行读或写,而不依赖Office 的 Excel,这不管对于ASP.net或Winform都非常有利,不用担心Excel进程的释放问题,服务器安全,设置,导出,导入“Excel智能识 别”,公式日期等问题,可以说以前的Excel问题,全都不用管了,它们可以很好的帮你解决,NPOI || MyXls == 研究几年Excel。

  NPOI开源地址: http://npoi.codeplex.com/

  MyXls开源地址: http://sourceforge.net/projects/myxls/

参考地址:


NPOI导出Excel表功能实现(多个工作簿): http://www.cnblogs.com/zhengjuzhuan/archive/2010/02/01/1661103.html
在 Server 端存取 Excel 檔案的利器:NPOI Library: http://msdn.microsoft.com/zh-tw/ee818993.aspx
 
NPOI通过DataTable导出和读取Excel
   public class NPOIHelper

    {

        /// <summary>

        /// DataTable导出到Excel文件,winform

        /// </summary>

        /// <param name="dtSource">源DataTable</param>

        /// <param name="strHeaderText">表头文本</param>

        /// <param name="strFileName">保存位置</param>

        public static void Export(DataTable dtSource, string strHeaderText, string strFileName)

        {

            using (MemoryStream ms = Export(dtSource, strHeaderText))

            {

                using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))

                {

                    byte[] data = ms.ToArray();

                    fs.Write(data, 0, data.Length);

                    fs.Flush();

                }

            }

        }



        /// <summary>

        /// DataTable导出到Excel的MemoryStream

        /// </summary>

        /// <param name="dtSource">源DataTable</param>

        /// <param name="strHeaderText">表头文本</param>

        public static MemoryStream Export(DataTable dtSource, string strHeaderText)

        {

            HSSFWorkbook workbook = new HSSFWorkbook();

            HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet();



            HSSFCellStyle dateStyle = (HSSFCellStyle)workbook.CreateCellStyle();

            HSSFDataFormat format = (HSSFDataFormat)workbook.CreateDataFormat();

            dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");



            //取得列宽

            int[] arrColWidth = new int[dtSource.Columns.Count];

            foreach (DataColumn item in dtSource.Columns)

            {

                arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;

            }

            for (int i = 0; i < dtSource.Rows.Count; i++)

            {

                for (int j = 0; j < dtSource.Columns.Count; j++)

                {

                    int intTemp = Encoding.GetEncoding(936).GetBytes(dtSource.Rows[i][j].ToString()).Length;

                    if (intTemp > arrColWidth[j])

                    {

                        arrColWidth[j] = intTemp;

                    }

                }

            }





            int rowIndex = 0;

            foreach (DataRow row in dtSource.Rows)

            {

                #region 新建表,填充表头,填充列头,样式

                if (rowIndex == 65535 || rowIndex == 0)

                {

                    if (rowIndex != 0)

                    {

                        sheet = (HSSFSheet)workbook.CreateSheet();

                    }



                    #region 表头及样式

                    {

                        HSSFRow headerRow = (HSSFRow)sheet.CreateRow(0);

                        headerRow.HeightInPoints = 25;

                        headerRow.CreateCell(0).SetCellValue(strHeaderText);



                        HSSFCellStyle headStyle = (HSSFCellStyle)workbook.CreateCellStyle();

                        headStyle.Alignment = HorizontalAlignment.Center;

                        HSSFFont font = (HSSFFont)workbook.CreateFont();

                        font.FontHeightInPoints = 20;

                        font.Boldweight = 700;

                        headStyle.SetFont(font);

                        headerRow.GetCell(0).CellStyle = headStyle;

                        sheet.AddMergedRegion(new Region(0, 0, 0, dtSource.Columns.Count - 1));



                    }

                    #endregion





                    #region 列头及样式

                    {

                        HSSFRow headerRow = (HSSFRow)sheet.CreateRow(1);

                        HSSFCellStyle headStyle = (HSSFCellStyle)workbook.CreateCellStyle();

                        headStyle.Alignment = HorizontalAlignment.Center;

                        HSSFFont font = (HSSFFont)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, (arrColWidth[column.Ordinal] + 1) * 256);

                        }



                    }

                    #endregion



                    rowIndex = 2;

                }

                #endregion





                #region 填充内容

                HSSFRow dataRow = (HSSFRow)sheet.CreateRow(rowIndex);

                foreach (DataColumn column in dtSource.Columns)

                {

                    HSSFCell newCell = (HSSFCell)dataRow.CreateCell(column.Ordinal);



                    string drValue = row[column].ToString();



                    switch (column.DataType.ToString())

                    {

                        case "System.String"://字符串类型

                            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 = false;

                            bool.TryParse(drValue, out boolV);

                            newCell.SetCellValue(boolV);

                            break;

                        case "System.Int16"://整型

                        case "System.Int32":

                        case "System.Int64":

                        case "System.Byte":

                            int intV = 0;

                            int.TryParse(drValue, out intV);

                            newCell.SetCellValue(intV);

                            break;

                        case "System.Decimal"://浮点型

                        case "System.Double":

                            double doubV = 0;

                            double.TryParse(drValue, out doubV);

                            newCell.SetCellValue(doubV);

                            break;

                        case "System.DBNull"://空值处理

                            newCell.SetCellValue("");

                            break;

                        default:

                            newCell.SetCellValue("");

                            break;

                    }



                }

                #endregion



                rowIndex++;

            }



            #region 合并相同列不成功

            ////合并列相同的

            //int columnCount = 0; //记录sheet一行的总列数

            //int start = 0;

            //int end = 0;

            //string cellText = "";

            //string temp = "";

            //for (int i = 0; i < workbook.NumberOfSheets; i++)  //NumberOfSheets是xls中总共的表数

            //{

            //    ISheet sht = workbook.GetSheetAt(i);   //读取当前表数据





            //    columnCount = sht.GetRow(3).LastCellNum;



            //    for (int j = 0; j <= columnCount; j++)

            //    {

            //        for (int k = 2; k < sheet.LastRowNum; k++)  //

            //        {

            //            ICell icell = sht.GetRow(k).GetCell(j);

            //            if (icell != null)

            //            {

            //                cellText = icell.ToString();//获取单元格的值



            //                if ((k + 1) <= sht.LastRowNum)  //比较当前列下一行单元格的值

            //                {

            //                    IRow iRow = sht.GetRow(k + 1);

            //                    if (iRow != null)

            //                    {

            //                        temp = iRow.GetCell(j).ToString();



            //                        if (cellText == temp)  //如果列上下值相同

            //                        {

            //                            //start = k;   //给开始的行号

            //                            //end = k + 1;

            //                            CellRangeAddress region = new CellRangeAddress(k, k + 1, j, j); //四个参数为:起始行,结束行,起始列,结束列

            //                            sht.AddMergedRegion(region);

            //                        }

            //                        //else   //列上下值不相同

            //                        //{

            //                        //    CellRangeAddress region = new CellRangeAddress(start,j , end, j);

            //                        //    sht.AddMergedRegion(region);

            //                        //    //合并之后重新给cellText赋值

            //                        //}

            //                    }







            //                }

            //            }







            //        }

            //    }

            //}

            

            #endregion





            using (MemoryStream ms = new MemoryStream())

            {

                workbook.Write(ms);

                ms.Flush();

                ms.Position = 0;



                //workbook.Dispose();//一般只用写这一个就OK了,他会遍历并释放所有资源,但当前版本有问题所以只释放sheet

                return ms;

            }

        }



        /// <summary>

        /// 用于Web导出

        /// </summary>

        /// <param name="dtSource">源DataTable</param>

        /// <param name="strHeaderText">表头文本</param>

        /// <param name="strFileName">文件名</param>

        public static void ExportByWeb(DataTable dtSource, string strHeaderText, string strFileName)

        {

            HttpContext curContext = HttpContext.Current;



            // 设置编码和附件格式

            curContext.Response.ContentType = "application/vnd.ms-excel";

            curContext.Response.ContentEncoding = Encoding.UTF8;

            curContext.Response.Charset = "";

            curContext.Response.AppendHeader("Content-Disposition",

              "attachment;filename=" + strFileName);

       



            curContext.Response.BinaryWrite(Export(dtSource, strHeaderText).GetBuffer());

            curContext.Response.End();

        }



        /// <summary>读取excel

        /// 默认第一行为标头

        /// </summary>

        /// <param name="strFileName">excel文档路径</param>

        /// <returns></returns>

        public static DataTable Import(string strFileName)

        {

            DataTable dt = new DataTable();



            HSSFWorkbook hssfworkbook;

            using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))

            {

                hssfworkbook = new HSSFWorkbook(file);

            }

            HSSFSheet sheet = (HSSFSheet)hssfworkbook.GetSheetAt(0);

            System.Collections.IEnumerator rows = sheet.GetRowEnumerator();



            HSSFRow headerRow = (HSSFRow)sheet.GetRow(0);

            int cellCount = headerRow.LastCellNum;



            for (int j = 0; j < cellCount; j++)

            {

                HSSFCell cell = (HSSFCell)headerRow.GetCell(j);

                dt.Columns.Add(cell.ToString());

            }



            for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++)

            {

                HSSFRow row = (HSSFRow)sheet.GetRow(i);

                DataRow dataRow = dt.NewRow();



                for (int j = row.FirstCellNum; j < cellCount; j++)

                {

                    if (row.GetCell(j) != null)

                        dataRow[j] = row.GetCell(j).ToString();

                }



                dt.Rows.Add(dataRow);

            }

            return dt;

        }

    }
View Code

本文参考并使用转自的博文地址:http://www.cnblogs.com/yongfa365/archive/2010/05/10/NPOI-MyXls-DataTable-To-Excel-From-Excel.html

你可能感兴趣的:(Datatable)