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/
下面来两个简单入门例子:
MyXls 快速入门例子:
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 }
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 }
NPOI 快速入门例子:
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 (MemoryStream ms = new MemoryStream())
34 {
35 using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
36 {
37 workbook.Write(fs);
38 }
39 }
40 workbook.Dispose();
41 }
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 (MemoryStream ms = new MemoryStream())
34 {
35 using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
36 {
37 workbook.Write(fs);
38 }
39 }
40 workbook.Dispose();
41 }
接下来是柳永法(yongfa365)'Blog封装的可以用在实际项目中的类,实现的功能有(仅NPOI):
- 支持web及winform从DataTable导出到Excel。
- 生成速度很快。
- 准确判断数据类型,不会出现×××转数值等上面提到的一系列问题。
- 如果单页条数大于65535时会新建工作表。
- 列宽自适应。
- 支持读取Excel。
- 调用方便,只一调用一个静态类就OK了。
- 因为测试期间发现MyXls导出速度要比NPOI慢3倍,而NPOI既能满足我们的导出需求,又能很好的满足我们的导入需求,所以只针对NPOI进行全方位功能实现及优化。
MyXls导出相关类:
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 }
92
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 }
92
转载于:https://blog.51cto.com/1030967291/1124153