您的位置:首页 > 其它

.net 使用NPOI或MyXls把DataTable导出到Excel Excel导入及导出

2013-03-12 16:38 429 查看
  从接触.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://tonyqus.sinaapp.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 }

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 }

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

1.支持web及winform从DataTable导出到Excel。

2.生成速度很快。

3.准确判断数据类型,不会出现身份证转数值等上面提到的一系列问题。

4.如果单页条数大于65535时会新建工作表。

5.列宽自适应。

6.支持读取Excel。

7.调用方便,只一调用一个静态类就OK了。

8.因为测试期间发现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

NPOI导入导出相关类:

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 }

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

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

参考地址:

NPOI导出Excel表功能实现(多个工作簿):/article/6313097.html

在 Server 端存取 Excel 檔案的利器:NPOI Library:http://msdn.microsoft.com/zh-tw/ee818993.aspx

ASP.NET使用NPOI类库导出Excel:/article/4973794.html

总结:

  通过以上分析,我们不难发现,用NPOI或MyXls代替是Excel是很明智的,在发文前,我看到NPOI及MyXls仍然在活跃的更新中。在使用过程中发现这两个组件极相似,以前看过文章说他们使用的内核是一样的。还有NPOI是国人开发的,且有相关中文文档,在很多地方有相关引用,下载量也很大。并且它支持Excel,看到MyXls相关问题基本上没人回答,所以推荐使用NPOI。MyXls可以直接Cell.Font.Bold操作,而NPOI得使用CellType多少感觉有点麻烦。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: