.net 通过NPOI或MyXls把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/
NPOI中文文档:http://www.cnblogs.com/tonyqus/archive/2009/04/12/1434209.html

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

下面来两个简单入门例子:
MyXls 快速入门例子:

view plain copy to clipboard print ?
  1. /// <summary>   
  2. /// MyXls简单Demo,快速入门代码   
  3. /// </summary>   
  4. /// <param name="dtSource"></param>   
  5. /// <param name="strFileName"></param>   
  6. /// <remarks>MyXls认为Excel的第一个单元格是:(1,1)</remarks>   
  7. /// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>   
  8. public static void ExportEasy(DataTable dtSource,  string strFileName)   
  9. {   
  10.     XlsDocument xls = new XlsDocument();   
  11.     Worksheet sheet = xls.Workbook.Worksheets.Add("Sheet1");   
  12.   
  13.     //填充表头   
  14.     foreach (DataColumn col in dtSource.Columns)   
  15.     {   
  16.         sheet.Cells.Add(1, col.Ordinal + 1, col.ColumnName);   
  17.     }   
  18.   
  19.     //填充内容   
  20.     for (int i = 0; i < dtSource.Rows.Count; i++)   
  21.     {   
  22.         for (int j = 0; j < dtSource.Columns.Count; j++)   
  23.         {   
  24.             sheet.Cells.Add(i + 2, j + 1, dtSource.Rows[i][j].ToString());   
  25.         }   
  26.     }   
  27.   
  28.     //保存   
  29.     xls.FileName = strFileName;   
  30.     xls.Save();   
  31. }  
/// <summary>
/// MyXls简单Demo,快速入门代码
/// </summary>
/// <param name="dtSource"></param>
/// <param name="strFileName"></param>
/// <remarks>MyXls认为Excel的第一个单元格是:(1,1)</remarks>
/// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>
public static void ExportEasy(DataTable dtSource,  string strFileName)
{
    XlsDocument xls = new XlsDocument();
    Worksheet sheet = xls.Workbook.Worksheets.Add("Sheet1");

    //填充表头
    foreach (DataColumn col in dtSource.Columns)
    {
        sheet.Cells.Add(1, col.Ordinal + 1, col.ColumnName);
    }

    //填充内容
    for (int i = 0; i < dtSource.Rows.Count; i++)
    {
        for (int j = 0; j < dtSource.Columns.Count; j++)
        {
            sheet.Cells.Add(i + 2, j + 1, dtSource.Rows[i][j].ToString());
        }
    }

    //保存
    xls.FileName = strFileName;
    xls.Save();
}

NPOI 快速入门例子:

view plain copy to clipboard print ?
  1. /// <summary>   
  2. /// NPOI简单Demo,快速入门代码   
  3. /// </summary>   
  4. /// <param name="dtSource"></param>   
  5. /// <param name="strFileName"></param>   
  6. /// <remarks>NPOI认为Excel的第一个单元格是:(0,0)</remarks>   
  7. /// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>   
  8. public static void ExportEasy(DataTable dtSource, string strFileName)   
  9. {   
  10.     HSSFWorkbook workbook = new HSSFWorkbook();   
  11.     HSSFSheet sheet = workbook.CreateSheet();   
  12.   
  13.     //填充表头   
  14.     HSSFRow dataRow = sheet.CreateRow(0);   
  15.     foreach (DataColumn column in dtSource.Columns)   
  16.     {   
  17.         dataRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);   
  18.     }   
  19.   
  20.   
  21.     //填充内容   
  22.     for (int i = 0; i < dtSource.Rows.Count; i++)   
  23.     {   
  24.         dataRow = sheet.CreateRow(i + 1);   
  25.         for (int j = 0; j < dtSource.Columns.Count; j++)   
  26.         {   
  27.             dataRow.CreateCell(j).SetCellValue(dtSource.Rows[i][j].ToString());   
  28.         }   
  29.     }   
  30.   
  31.   
  32.     //保存   
  33.     using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))   
  34.     {   
  35.         workbook.Write(fs);   
  36.     }   
  37.     workbook.Dispose();   
  38. }  
/// <summary>
/// NPOI简单Demo,快速入门代码
/// </summary>
/// <param name="dtSource"></param>
/// <param name="strFileName"></param>
/// <remarks>NPOI认为Excel的第一个单元格是:(0,0)</remarks>
/// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>
public static void ExportEasy(DataTable dtSource, string strFileName)
{
    HSSFWorkbook workbook = new HSSFWorkbook();
    HSSFSheet sheet = workbook.CreateSheet();

    //填充表头
    HSSFRow dataRow = sheet.CreateRow(0);
    foreach (DataColumn column in dtSource.Columns)
    {
        dataRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
    }


    //填充内容
    for (int i = 0; i < dtSource.Rows.Count; i++)
    {
        dataRow = sheet.CreateRow(i + 1);
        for (int j = 0; j < dtSource.Columns.Count; j++)
        {
            dataRow.CreateCell(j).SetCellValue(dtSource.Rows[i][j].ToString());
        }
    }


    //保存
    using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
    {
        workbook.Write(fs);
    }
    workbook.Dispose();
}

接下来是柳永法(yongfa365)'Blog封装的可以用在实际项目中的类,实现的功能有(仅NPOI):

  1. 支持web及winform从DataTable导出到Excel。
  2. 生成速度很快。
  3. 准确判断数据类型,不会出现身份证转数值等上面提到的一系列问题。
  4. 如果单页条数大于65535时会新建工作表。
  5. 列宽自适应。
  6. 支持读取Excel。
  7. 调用方便,只一调用一个静态类就OK了。

因为测试期间发现MyXls导出速度要比NPOI慢3倍,而NPOI既能满足我们的导出需求,又能很好的满足我们的导入需求,所以只针对NPOI进行全方位功能实现及优化。

MyXls导出相关类:

view plain copy to clipboard print ?
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Linq;   
  4. using System.Text;   
  5. using org.in2bits.MyXls;   
  6. using org.in2bits.MyXls.ByteUtil;   
  7. using System.Data;   
  8.   
  9. class ExcelHelper   
  10. {   
  11.     public static void Export(DataTable dtSource, string strHeaderText, string strFileName)   
  12.     {   
  13.         XlsDocument xls = new XlsDocument();   
  14.         xls.FileName = DateTime.Now.ToString("yyyyMMddHHmmssffff", System.Globalization.DateTimeFormatInfo.InvariantInfo);   
  15.         xls.SummaryInformation.Author = "yongfa365"//填加xls文件作者信息   
  16.         xls.SummaryInformation.NameOfCreatingApplication = "liu yongfa"//填加xls文件创建程序信息   
  17.         xls.SummaryInformation.LastSavedBy = "LastSavedBy"//填加xls文件最后保存者信息   
  18.         xls.SummaryInformation.Comments = "Comments"//填加xls文件作者信息   
  19.         xls.SummaryInformation.Title = "title"//填加xls文件标题信息   
  20.         xls.SummaryInformation.Subject = "Subject";//填加文件主题信息   
  21.         xls.DocumentSummaryInformation.Company = "company";//填加文件公司信息   
  22.   
  23.   
  24.         Worksheet sheet = xls.Workbook.Worksheets.Add("Sheet1");//状态栏标题名称   
  25.         Cells cells = sheet.Cells;   
  26.   
  27.         foreach (DataColumn col in dtSource.Columns)   
  28.         {   
  29.             Cell cell = cells.Add(1, col.Ordinal + 1, col.ColumnName);   
  30.             cell.Font.FontFamily = FontFamilies.Roman; //字体   
  31.             cell.Font.Bold = true;  //字体为粗体     
  32.   
  33.         }  
  34.         #region 填充内容   
  35.         XF dateStyle = xls.NewXF();   
  36.         dateStyle.Format = "yyyy-mm-dd";   
  37.   
  38.         for (int i = 0; i < dtSource.Rows.Count; i++)   
  39.         {   
  40.             for (int j = 0; j < dtSource.Columns.Count; j++)   
  41.             {   
  42.   
  43.                 int rowIndex = i + 2;   
  44.                 int colIndex = j + 1;   
  45.                 string drValue = dtSource.Rows[i][j].ToString();   
  46.   
  47.                 switch (dtSource.Rows[i][j].GetType().ToString())   
  48.                 {   
  49.                     case "System.String"://字符串类型   
  50.                         cells.Add(rowIndex, colIndex, drValue);   
  51.                         break;   
  52.                     case "System.DateTime"://日期类型   
  53.                         DateTime dateV;   
  54.                         DateTime.TryParse(drValue, out dateV);   
  55.                         cells.Add(rowIndex, colIndex, dateV, dateStyle);   
  56.                         break;   
  57.                     case "System.Boolean"://布尔型   
  58.                         bool boolV = false;   
  59.                         bool.TryParse(drValue, out boolV);   
  60.                         cells.Add(rowIndex, colIndex, boolV);   
  61.                         break;   
  62.                     case "System.Int16"://整型   
  63.                     case "System.Int32":   
  64.                     case "System.Int64":   
  65.                     case "System.Byte":   
  66.                         int intV = 0;   
  67.                         int.TryParse(drValue, out intV);   
  68.                         cells.Add(rowIndex, colIndex, intV);   
  69.                         break;   
  70.                     case "System.Decimal"://浮点型   
  71.                     case "System.Double":   
  72.                         double doubV = 0;   
  73.                         double.TryParse(drValue, out doubV);   
  74.                         cells.Add(rowIndex, colIndex, doubV);   
  75.                         break;   
  76.                     case "System.DBNull"://空值处理   
  77.                         cells.Add(rowIndex, colIndex, null);   
  78.                         break;   
  79.                     default:   
  80.                         cells.Add(rowIndex, colIndex, null);   
  81.                         break;   
  82.                 }   
  83.             }   
  84.         }  
  85.  
  86.         #endregion   
  87.   
  88.         xls.FileName = strFileName;   
  89.         xls.Save();   
  90.     }   
  91. }  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using org.in2bits.MyXls;
using org.in2bits.MyXls.ByteUtil;
using System.Data;

class ExcelHelper
{
    public static void Export(DataTable dtSource, string strHeaderText, string strFileName)
    {
        XlsDocument xls = new XlsDocument();
        xls.FileName = DateTime.Now.ToString("yyyyMMddHHmmssffff", System.Globalization.DateTimeFormatInfo.InvariantInfo);
        xls.SummaryInformation.Author = "yongfa365"; //填加xls文件作者信息
        xls.SummaryInformation.NameOfCreatingApplication = "liu yongfa"; //填加xls文件创建程序信息
        xls.SummaryInformation.LastSavedBy = "LastSavedBy"; //填加xls文件最后保存者信息
        xls.SummaryInformation.Comments = "Comments"; //填加xls文件作者信息
        xls.SummaryInformation.Title = "title"; //填加xls文件标题信息
        xls.SummaryInformation.Subject = "Subject";//填加文件主题信息
        xls.DocumentSummaryInformation.Company = "company";//填加文件公司信息


        Worksheet sheet = xls.Workbook.Worksheets.Add("Sheet1");//状态栏标题名称
        Cells cells = sheet.Cells;

        foreach (DataColumn col in dtSource.Columns)
        {
            Cell cell = cells.Add(1, col.Ordinal + 1, col.ColumnName);
            cell.Font.FontFamily = FontFamilies.Roman; //字体
            cell.Font.Bold = true;  //字体为粗体  

        }
        #region 填充内容
        XF dateStyle = xls.NewXF();
        dateStyle.Format = "yyyy-mm-dd";

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

                int rowIndex = i + 2;
                int colIndex = j + 1;
                string drValue = dtSource.Rows[i][j].ToString();

                switch (dtSource.Rows[i][j].GetType().ToString())
                {
                    case "System.String"://字符串类型
                        cells.Add(rowIndex, colIndex, drValue);
                        break;
                    case "System.DateTime"://日期类型
                        DateTime dateV;
                        DateTime.TryParse(drValue, out dateV);
                        cells.Add(rowIndex, colIndex, dateV, dateStyle);
                        break;
                    case "System.Boolean"://布尔型
                        bool boolV = false;
                        bool.TryParse(drValue, out boolV);
                        cells.Add(rowIndex, colIndex, boolV);
                        break;
                    case "System.Int16"://整型
                    case "System.Int32":
                    case "System.Int64":
                    case "System.Byte":
                        int intV = 0;
                        int.TryParse(drValue, out intV);
                        cells.Add(rowIndex, colIndex, intV);
                        break;
                    case "System.Decimal"://浮点型
                    case "System.Double":
                        double doubV = 0;
                        double.TryParse(drValue, out doubV);
                        cells.Add(rowIndex, colIndex, doubV);
                        break;
                    case "System.DBNull"://空值处理
                        cells.Add(rowIndex, colIndex, null);
                        break;
                    default:
                        cells.Add(rowIndex, colIndex, null);
                        break;
                }
            }
        }

        #endregion

        xls.FileName = strFileName;
        xls.Save();
    }
}

NPOI导入导出相关类:

view plain copy to clipboard print ?
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Data;   
  4. using System.IO;   
  5. using System.Text;   
  6. using System.Web;   
  7. using NPOI;   
  8. using NPOI.HPSF;   
  9. using NPOI.HSSF;   
  10. using NPOI.HSSF.UserModel;   
  11. using NPOI.HSSF.Util;   
  12. using NPOI.POIFS;   
  13. using NPOI.Util;   
  14.   
  15.   
  16. public class ExcelHelper   
  17. {   
  18.     /// <summary>   
  19.     /// DataTable导出到Excel文件   
  20.     /// </summary>   
  21.     /// <param name="dtSource">源DataTable</param>   
  22.     /// <param name="strHeaderText">表头文本</param>   
  23.     /// <param name="strFileName">保存位置</param>   
  24.     /// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>   
  25.     public static void Export(DataTable dtSource, string strHeaderText, string strFileName)   
  26.     {   
  27.         using (MemoryStream ms = Export(dtSource, strHeaderText))   
  28.         {   
  29.             using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))   
  30.             {   
  31.                 byte[] data = ms.ToArray();   
  32.                 fs.Write(data, 0, data.Length);   
  33.                 fs.Flush();   
  34.             }   
  35.         }   
  36.     }   
  37.   
  38.     /// <summary>   
  39.     /// DataTable导出到Excel的MemoryStream   
  40.     /// </summary>   
  41.     /// <param name="dtSource">源DataTable</param>   
  42.     /// <param name="strHeaderText">表头文本</param>   
  43.     /// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>   
  44.     public static MemoryStream Export(DataTable dtSource, string strHeaderText)   
  45.     {   
  46.         HSSFWorkbook workbook = new HSSFWorkbook();   
  47.         HSSFSheet sheet = workbook.CreateSheet();  
  48.  
  49.         #region 右击文件 属性信息   
  50.         {   
  51.             DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();   
  52.             dsi.Company = "http://www.yongfa365.com/";   
  53.             workbook.DocumentSummaryInformation = dsi;   
  54.   
  55.             SummaryInformation si = PropertySetFactory.CreateSummaryInformation();   
  56.             si.Author = "柳永法"//填加xls文件作者信息   
  57.             si.ApplicationName = "NPOI测试程序"//填加xls文件创建程序信息   
  58.             si.LastAuthor = "柳永法2"//填加xls文件最后保存者信息   
  59.             si.Comments = "说明信息"//填加xls文件作者信息   
  60.             si.Title = "NPOI测试"//填加xls文件标题信息   
  61.             si.Subject = "NPOI测试Demo";//填加文件主题信息   
  62.             si.CreateDateTime = DateTime.Now;   
  63.             workbook.SummaryInformation = si;   
  64.         }  
  65.         #endregion   
  66.   
  67.         HSSFCellStyle dateStyle = workbook.CreateCellStyle();   
  68.         HSSFDataFormat format = workbook.CreateDataFormat();   
  69.         dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");   
  70.   
  71.         //取得列宽   
  72.         int[] arrColWidth = new int[dtSource.Columns.Count];   
  73.         foreach (DataColumn item in dtSource.Columns)   
  74.         {   
  75.             arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;   
  76.         }   
  77.         for (int i = 0; i < dtSource.Rows.Count; i++)   
  78.         {   
  79.             for (int j = 0; j < dtSource.Columns.Count; j++)   
  80.             {   
  81.                 int intTemp = Encoding.GetEncoding(936).GetBytes(dtSource.Rows[i][j].ToString()).Length;   
  82.                 if (intTemp > arrColWidth[j])   
  83.                 {   
  84.                     arrColWidth[j] = intTemp;   
  85.                 }   
  86.             }   
  87.         }   
  88.   
  89.   
  90.   
  91.         int rowIndex = 0;   
  92.   
  93.         foreach (DataRow row in dtSource.Rows)   
  94.         {  
  95.             #region 新建表,填充表头,填充列头,样式   
  96.             if (rowIndex == 65535 || rowIndex == 0)   
  97.             {   
  98.                 if (rowIndex != 0)   
  99.                 {   
  100.                     sheet = workbook.CreateSheet();   
  101.                 }  
  102.  
  103.                 #region 表头及样式   
  104.                 {   
  105.                     HSSFRow headerRow = sheet.CreateRow(0);   
  106.                     headerRow.HeightInPoints = 25;   
  107.                     headerRow.CreateCell(0).SetCellValue(strHeaderText);   
  108.   
  109.                     HSSFCellStyle headStyle = workbook.CreateCellStyle();   
  110.                     headStyle.Alignment = CellHorizontalAlignment.CENTER;   
  111.                     HSSFFont font = workbook.CreateFont();   
  112.                     font.FontHeightInPoints = 20;   
  113.                     font.Boldweight = 700;   
  114.                     headStyle.SetFont(font);   
  115.   
  116.                     headerRow.GetCell(0).CellStyle = headStyle;   
  117.   
  118.                     sheet.AddMergedRegion(new Region(0, 0, 0, dtSource.Columns.Count - 1));   
  119.                     headerRow.Dispose();   
  120.                 }  
  121.                 #endregion  
  122.  
  123.  
  124.                 #region 列头及样式   
  125.                 {   
  126.                     HSSFRow headerRow = sheet.CreateRow(1);   
  127.   
  128.   
  129.                     HSSFCellStyle headStyle = workbook.CreateCellStyle();   
  130.                     headStyle.Alignment = CellHorizontalAlignment.CENTER;   
  131.                     HSSFFont font = workbook.CreateFont();   
  132.                     font.FontHeightInPoints = 10;   
  133.                     font.Boldweight = 700;   
  134.                     headStyle.SetFont(font);   
  135.   
  136.   
  137.                     foreach (DataColumn column in dtSource.Columns)   
  138.                     {   
  139.                         headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);   
  140.                         headerRow.GetCell(column.Ordinal).CellStyle = headStyle;   
  141.   
  142.                         //设置列宽   
  143.                         sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256);   
  144.   
  145.                     }   
  146.                     headerRow.Dispose();   
  147.                 }  
  148.                 #endregion   
  149.   
  150.                 rowIndex = 2;   
  151.             }  
  152.             #endregion  
  153.  
  154.  
  155.             #region 填充内容   
  156.             HSSFRow dataRow = sheet.CreateRow(rowIndex);   
  157.             foreach (DataColumn column in dtSource.Columns)   
  158.             {   
  159.                 HSSFCell newCell = dataRow.CreateCell(column.Ordinal);   
  160.   
  161.                 string drValue = row[column].ToString();   
  162.   
  163.                 switch (column.DataType.ToString())   
  164.                 {   
  165.                     case "System.String"://字符串类型   
  166.                         newCell.SetCellValue(drValue);   
  167.                         break;   
  168.                     case "System.DateTime"://日期类型   
  169.                         DateTime dateV;   
  170.                         DateTime.TryParse(drValue, out dateV);   
  171.                         newCell.SetCellValue(dateV);   
  172.   
  173.                         newCell.CellStyle = dateStyle;//格式化显示   
  174.                         break;   
  175.                     case "System.Boolean"://布尔型   
  176.                         bool boolV = false;   
  177.                         bool.TryParse(drValue, out boolV);   
  178.                         newCell.SetCellValue(boolV);   
  179.                         break;   
  180.                     case "System.Int16"://整型   
  181.                     case "System.Int32":   
  182.                     case "System.Int64":   
  183.                     case "System.Byte":   
  184.                         int intV = 0;   
  185.                         int.TryParse(drValue, out intV);   
  186.                         newCell.SetCellValue(intV);   
  187.                         break;   
  188.                     case "System.Decimal"://浮点型   
  189.                     case "System.Double":   
  190.                         double doubV = 0;   
  191.                         double.TryParse(drValue, out doubV);   
  192.                         newCell.SetCellValue(doubV);   
  193.                         break;   
  194.                     case "System.DBNull"://空值处理   
  195.                         newCell.SetCellValue("");   
  196.                         break;   
  197.                     default:   
  198.                         newCell.SetCellValue("");   
  199.                         break;   
  200.                 }   
  201.   
  202.             }  
  203.             #endregion   
  204.   
  205.             rowIndex++;   
  206.         }   
  207.   
  208.   
  209.         using (MemoryStream ms = new MemoryStream())   
  210.         {   
  211.             workbook.Write(ms);   
  212.             ms.Flush();   
  213.             ms.Position = 0;   
  214.   
  215.             sheet.Dispose();   
  216.            //workbook.Dispose();//一般只用写这一个就OK了,他会遍历并释放所有资源,但当前版本有问题所以只释放sheet   
  217.             return ms;   
  218.         }   
  219.   
  220.     }   
  221.   
  222.   
  223.     /// <summary>   
  224.     /// 用于Web导出   
  225.     /// </summary>   
  226.     /// <param name="dtSource">源DataTable</param>   
  227.     /// <param name="strHeaderText">表头文本</param>   
  228.     /// <param name="strFileName">文件名</param>   
  229.     /// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>   
  230.     public static void ExportByWeb(DataTable dtSource, string strHeaderText, string strFileName)   
  231.     {   
  232.   
  233.         HttpContext curContext = HttpContext.Current;   
  234.   
  235.         // 设置编码和附件格式   
  236.         curContext.Response.ContentType = "application/vnd.ms-excel";   
  237.         curContext.Response.ContentEncoding = Encoding.UTF8;   
  238.         curContext.Response.Charset = "";   
  239.         curContext.Response.AppendHeader("Content-Disposition",    
  240.             "attachment;filename=" + HttpUtility.UrlEncode(strFileName, Encoding.UTF8));   
  241.   
  242.         curContext.Response.BinaryWrite(Export(dtSource, strHeaderText).GetBuffer());   
  243.         curContext.Response.End();   
  244.   
  245.     }   
  246.   
  247.   
  248.     /// <summary>读取excel   
  249.     /// 默认第一行为标头   
  250.     /// </summary>   
  251.     /// <param name="strFileName">excel文档路径</param>   
  252.     /// <returns></returns>   
  253.     public static DataTable Import(string strFileName)   
  254.     {   
  255.         DataTable dt = new DataTable();   
  256.   
  257.         HSSFWorkbook hssfworkbook;   
  258.         using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))   
  259.         {   
  260.             hssfworkbook = new HSSFWorkbook(file);   
  261.         }   
  262.         HSSFSheet sheet = hssfworkbook.GetSheetAt(0);   
  263.         System.Collections.IEnumerator rows = sheet.GetRowEnumerator();   
  264.   
  265.         HSSFRow headerRow = sheet.GetRow(0);   
  266.         int cellCount = headerRow.LastCellNum;   
  267.   
  268.         for (int j = 0; j < cellCount; j++)   
  269.         {   
  270.             HSSFCell cell = headerRow.GetCell(j);   
  271.             dt.Columns.Add(cell.ToString());   
  272.         }   
  273.   
  274.         for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++)   
  275.         {   
  276.             HSSFRow row = sheet.GetRow(i);   
  277.             DataRow dataRow = dt.NewRow();   
  278.   
  279.             for (int j = row.FirstCellNum; j < cellCount; j++)   
  280.             {   
  281.                 if (row.GetCell(j) != null)   
  282.                     dataRow[j] = row.GetCell(j).ToString();   
  283.             }   
  284.   
  285.             dt.Rows.Add(dataRow);   
  286.         }   
  287.         return dt;   
  288.     }   
  289.   
  290. }  
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Web;
using NPOI;
using NPOI.HPSF;
using NPOI.HSSF;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.POIFS;
using NPOI.Util;


public class ExcelHelper
{
    /// <summary>
    /// DataTable导出到Excel文件
    /// </summary>
    /// <param name="dtSource">源DataTable</param>
    /// <param name="strHeaderText">表头文本</param>
    /// <param name="strFileName">保存位置</param>
    /// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>
    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>
    /// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>
    public static MemoryStream Export(DataTable dtSource, string strHeaderText)
    {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.CreateSheet();

        #region 右击文件 属性信息
        {
            DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
            dsi.Company = "http://www.yongfa365.com/";
            workbook.DocumentSummaryInformation = dsi;

            SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
            si.Author = "柳永法"; //填加xls文件作者信息
            si.ApplicationName = "NPOI测试程序"; //填加xls文件创建程序信息
            si.LastAuthor = "柳永法2"; //填加xls文件最后保存者信息
            si.Comments = "说明信息"; //填加xls文件作者信息
            si.Title = "NPOI测试"; //填加xls文件标题信息
            si.Subject = "NPOI测试Demo";//填加文件主题信息
            si.CreateDateTime = DateTime.Now;
            workbook.SummaryInformation = si;
        }
        #endregion

        HSSFCellStyle dateStyle = workbook.CreateCellStyle();
        HSSFDataFormat format = 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 = workbook.CreateSheet();
                }

                #region 表头及样式
                {
                    HSSFRow headerRow = sheet.CreateRow(0);
                    headerRow.HeightInPoints = 25;
                    headerRow.CreateCell(0).SetCellValue(strHeaderText);

                    HSSFCellStyle headStyle = workbook.CreateCellStyle();
                    headStyle.Alignment = CellHorizontalAlignment.CENTER;
                    HSSFFont font = 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));
                    headerRow.Dispose();
                }
                #endregion


                #region 列头及样式
                {
                    HSSFRow headerRow = sheet.CreateRow(1);


                    HSSFCellStyle headStyle = workbook.CreateCellStyle();
                    headStyle.Alignment = CellHorizontalAlignment.CENTER;
                    HSSFFont 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, (arrColWidth[column.Ordinal] + 1) * 256);

                    }
                    headerRow.Dispose();
                }
                #endregion

                rowIndex = 2;
            }
            #endregion


            #region 填充内容
            HSSFRow dataRow = sheet.CreateRow(rowIndex);
            foreach (DataColumn column in dtSource.Columns)
            {
                HSSFCell newCell = 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++;
        }


        using (MemoryStream ms = new MemoryStream())
        {
            workbook.Write(ms);
            ms.Flush();
            ms.Position = 0;

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

    }


    /// <summary>
    /// 用于Web导出
    /// </summary>
    /// <param name="dtSource">源DataTable</param>
    /// <param name="strHeaderText">表头文本</param>
    /// <param name="strFileName">文件名</param>
    /// <Author>柳永法 http://www.yongfa365.com/ 2010-5-8 22:21:41</Author>
    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=" + HttpUtility.UrlEncode(strFileName, Encoding.UTF8));

        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 = hssfworkbook.GetSheetAt(0);
        System.Collections.IEnumerator rows = sheet.GetRowEnumerator();

        HSSFRow headerRow = sheet.GetRow(0);
        int cellCount = headerRow.LastCellNum;

        for (int j = 0; j < cellCount; j++)
        {
            HSSFCell cell = headerRow.GetCell(j);
            dt.Columns.Add(cell.ToString());
        }

        for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++)
        {
            HSSFRow row = 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;
    }

}

以上相关源码及测试用例下载地址:

http://download.csdn.net/source/2330821

参考地址:

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
ASP.NET使用NPOI类库导出Excel:http://www.cnblogs.com/niunan/archive/2010/03/30/1700706.html

总结:

  通过以上分析,我们不难发现,用NPOI或MyXls代替是Excel是很明智的,在发文前,我看到NPOI及MyXls仍然在活跃的更新中。在使用过程中发现这两个组件极相似,以前看过文章说他们使用的内核是一样的。还有NPOI是国人开发的,且有相关中文文档,在很多地方有相关引用,下载量也很大。并且它支持Excel,看到MyXls相关问题基本上没人回答,所以推荐使用NPOI。MyXls可以直接Cell.Font.Bold操作,而NPOI得使用CellType多少感觉有点麻烦。

 

此文提到这个版本有个BUG,最新版本已经更正此BUG,最新版代码已经更新到我的 SVN上,有兴趣的可以弄下来看看

你可能感兴趣的:(.net 通过NPOI或MyXls把DataTable导出到Excel)