Excel导入 支持2003和2007

excel导入到数据库,1.上传excel,2.读取excel数据,3.写数据到数据库(批量导入推荐使用SqlBulkCopy,或OracleBulkCopy)

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data;
  4 using System.IO;
  5 using System.Linq;
  6 using System.Text.RegularExpressions;
  7 using System.Web;
  8 using NPOI.HSSF.UserModel;
  9 using NPOI.SS.UserModel;
 10 using NPOI.XSSF.UserModel;
 11 
 12 //支持excel 2007 或2003 导入
 13 
 14 namespace FrameWork.Helper
 15 {
 16     public partial class ExcelHelper
 17     {
 18         /// <summary>
 19         ///     上传文件到服务器并返回文件路径
 20         /// </summary>
 21         /// <param name="file">上载的文件对象HttpPostedFile</param>
 22         /// <param name="savePath">相对存放路径【例:"uploads/excel/"】</param>
 23         /// <param name="maxContentLength">上载文件的最大允许大小(以字节为单位)</param>
 24         /// <returns>返回上传成功的excel的路径</returns>
 25         public static string SaveExcelFile(HttpPostedFileBase file, string savePath, int maxContentLength = 1024*1024*10)
 26         {
 27             if (file == null || file.ContentLength <= 0)
 28             {
 29                 throw new Exception("文件不能为空");
 30             }
 31             var filesize = file.ContentLength; //获取上传文件的大小单位为字节byte
 32             if (filesize > maxContentLength)
 33             {
 34                 throw new Exception("文件超过最大允许");
 35             }
 36             var filename = Path.GetFileName(file.FileName);
 37             if (!(IsExcel2003(filename) || IsExcel2007(filename)))
 38             {
 39                 throw new Exception("文件格式不正确");
 40             }
 41             var fileEx = Path.GetExtension(filename); //获取上传文件的扩展名
 42             var noExFileName = Path.GetFileNameWithoutExtension(filename); //获取无扩展名的文件名
 43 
 44             var newfileName = noExFileName + DateTime.Now.ToString("yyyyMMddhhmmss") + fileEx;
 45             var path = AppDomain.CurrentDomain.BaseDirectory + savePath;
 46             if (!Directory.Exists(path)) Directory.CreateDirectory(path);
 47             savePath = Path.Combine(path, newfileName);
 48             file.SaveAs(savePath);
 49             return savePath;
 50         }
 51 
 52 
 53         /// <summary>
 54         ///     读取excel到DataTable
 55         ///     默认第一行为表头
 56         /// </summary>
 57         /// <param name="path">excel文档的绝对访问路径【例:C:\abc.xlsx】</param>
 58         /// <param name="defaultColumn">默认字段和默认值</param>
 59         /// <param name="transColumn">
 60         ///     需要转换的列头字典例:transColumn=new Dictionary<string, string />(){{"姓名","name"}};
 61         ///     程序读取到excel 第一行的列头姓名,就自动转换成name ,name 才是数据表中的列头
 62         /// </param>
 63         /// <returns></returns>
 64         public static DataTable RenderDataTableFromExcel(string path, Dictionary<string, object> defaultColumn = null,
 65             Dictionary<string, string> transColumn = null)
 66         {
 67             string msg;
 68             if (!ValidateExcel(path, out msg))
 69             {
 70                 throw new Exception(msg);
 71             }
 72             var dt = new DataTable();
 73             if (IsExcel2003(path))
 74             {
 75                 ReadFileData2003(path, dt, defaultColumn, transColumn);
 76             }
 77             else
 78             {
 79                 ReadFileData2007(path, dt, defaultColumn, transColumn);
 80             }
 81             return dt;
 82         }
 83 
 84         /// <summary>
 85         ///     2003
 86         /// </summary>
 87         /// <param name="path"></param>
 88         /// <param name="dt"></param>
 89         /// <param name="defaultColumn">默认字段和默认值</param>
 90         /// <param name="transColumn">
 91         ///     需要转换的列头字典例:transColumn=new Dictionary<string, string />(){{"姓名","name"}};
 92         ///     程序读取到excel 第一行的列头姓名,就自动转换成name ,name 才是数据表中的列头
 93         /// </param>
 94         private static void ReadFileData2003(string path, DataTable dt, Dictionary<string, object> defaultColumn = null,
 95             Dictionary<string, string> transColumn = null)
 96         {
 97             HSSFWorkbook xssFworkbook;
 98             using (var file = new FileStream(path, FileMode.Open, FileAccess.Read))
 99             {
100                 xssFworkbook = new HSSFWorkbook(file);
101             }
102             var sheet = (HSSFSheet)xssFworkbook.GetSheetAt(0);
103             var rows = sheet.GetRowEnumerator();
104 
105             var headerRow = (HSSFRow)sheet.GetRow(0);
106             int cellCount = headerRow.LastCellNum;
107 
108             for (var j = 0; j < cellCount; j++)
109             {
110                 var cell = (HSSFCell)headerRow.GetCell(j);
111                 var column = cell.ToString();
112 
113                 if (transColumn != null && transColumn.ContainsKey(column))
114                 {
115                     column = transColumn[column];
116                 }
117                 dt.Columns.Add(column);
118             }
119             //加入默认列和值
120             if (defaultColumn != null && defaultColumn.Any())
121             {
122                 foreach (var key in defaultColumn.Keys)
123                 {
124                     dt.Columns.Add(key);
125                 }
126             }
127 
128             for (var i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++)
129             {
130                 var row = (HSSFRow)sheet.GetRow(i);
131                 var dataRow = dt.NewRow();
132 
133                 for (int j = row.FirstCellNum; j < cellCount; j++)
134                 {
135                     if (row.GetCell(j) != null)
136                         //dataRow[j] = row.GetCell(j).ToString();
137                         dataRow[j] = GetICellValue(row.GetCell(j));
138                 }
139                 //加入默认列和值
140                 if (defaultColumn != null && defaultColumn.Any())
141                 {
142                     for (var j = 0; j < defaultColumn.Keys.Count; j++)
143                     {
144                         var key = defaultColumn.Keys.ElementAt(j);
145                         dataRow[cellCount + j] = defaultColumn[key];
146                     }
147                 }
148                 dt.Rows.Add(dataRow);
149             }
150         }
151 
152         /// <summary>
153         ///     转换不同格式的单元格数据
154         /// </summary>
155         /// <param name="cell"></param>
156         /// <returns></returns>
157         private static object GetICellValue(ICell cell)
158         {
159             object value = null;
160             switch (cell.CellType)
161             {
162                 case CellType.Blank:
163                     break;
164                 case CellType.Boolean:
165                     value = cell.BooleanCellValue ? "1" : "0";
166                     break;
167                 case CellType.Error:
168                     value = cell.ErrorCellValue;
169                     break;
170                 case CellType.Formula:
171                     //alue = "=" + cell.CellFormula; break;
172                     // HSSFFormulaEvaluator e = new HSSFFormulaEvaluator(hssfworkbook);
173                     // dr[iRow] = e.Evaluate(cell).StringValue;
174                     try
175                     {
176                         value = cell.StringCellValue;
177                     }
178                     catch
179                     {
180                         try
181                         {
182                             value = cell.NumericCellValue;
183                         }
184                         catch
185                         {
186                             ;
187                         }
188                     }
189                     break;
190                 case CellType.Numeric:
191                     //NPOI中数字和日期都是NUMERIC类型的,这里对其进行判断是否是日期类型
192                     if (DateUtil.IsCellDateFormatted(cell)) //日期类型
193                     {
194                         value = cell.DateCellValue;
195                     }
196                     else //其他数字类型
197                     {
198                         value = cell.NumericCellValue;
199                     }
200 
201                     break;
202                 case CellType.String:
203                     value = cell.StringCellValue;
204                     break;
205                 case CellType.Unknown:
206                     break;
207             }
208             return value;
209         }
210 
211         /// <summary>
212         ///     2007
213         /// </summary>
214         /// <param name="path"></param>
215         /// <param name="dt"></param>
216         /// <param name="defaultColumn">默认字段和默认值</param>
217         /// <param name="transColumn">
218         ///     需要转换的列头字典例:transColumn=new Dictionary<string, string />(){{"姓名","name"}};
219         ///     程序读取到excel 第一行的列头姓名,就自动转换成name ,name 才是数据表中的列头
220         ///     因为导入操作者的模板列头是中文的,不和数据表头一一对应
221         /// </param>
222         private static void ReadFileData2007(string path, DataTable dt, Dictionary<string, object> defaultColumn = null,
223             Dictionary<string, string> transColumn = null)
224         {
225             XSSFWorkbook xssFworkbook;
226             using (var file = new FileStream(path, FileMode.Open, FileAccess.Read))
227             {
228                 xssFworkbook = new XSSFWorkbook(file);
229             }
230             var sheet = (XSSFSheet)xssFworkbook.GetSheetAt(0);
231             var rows = sheet.GetRowEnumerator();
232 
233             var headerRow = (XSSFRow)sheet.GetRow(0);
234             int cellCount = headerRow.LastCellNum;
235 
236             for (var j = 0; j < cellCount; j++)
237             {
238                 var cell = (XSSFCell)headerRow.GetCell(j);
239                 var column = cell.ToString();
240                 //如果上传模板列头和表列头不对应,需要转换列头
241                 if (transColumn != null && transColumn.ContainsKey(column))
242                 {
243                     column = transColumn[column];
244                 }
245                 dt.Columns.Add(column);
246             }
247             //加入默认列和值
248             if (defaultColumn != null && defaultColumn.Any())
249             {
250                 foreach (var key in defaultColumn.Keys)
251                 {
252                     dt.Columns.Add(key);
253                 }
254             }
255 
256             for (var i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++)
257             {
258                 var row = (XSSFRow)sheet.GetRow(i);
259                 var dataRow = dt.NewRow();
260 
261                 for (int j = row.FirstCellNum; j < cellCount; j++)
262                 {
263                     if (row.GetCell(j) != null)
264                         //dataRow[j] = row.GetCell(j).ToString();
265                         dataRow[j] = GetICellValue(row.GetCell(j));
266                 }
267 
268                 //加入默认列和值
269                 if (defaultColumn != null && defaultColumn.Any())
270                 {
271                     for (var j = 0; j < defaultColumn.Keys.Count; j++)
272                     {
273                         var key = defaultColumn.Keys.ElementAt(j);
274                         dataRow[cellCount + j] = defaultColumn[key];
275                     }
276                 }
277                 dt.Rows.Add(dataRow);
278             }
279         }
280 
281         /// <summary>
282         ///     验证是否是excel
283         /// </summary>
284         /// <param name="filePath">文件路径</param>
285         /// <param name="errorMess">异常信息</param>
286         /// <returns></returns>
287         public static bool ValidateExcel(string filePath, out string errorMess)
288         {
289             /** 检查文件名是否为空或者是否是Excel格式的文件 */
290             if (filePath == null || !(IsExcel2003(filePath) || IsExcel2007(filePath)))
291             {
292                 errorMess = "文件名不是excel格式";
293                 return false;
294             }
295 
296             /** 检查文件是否存在 */
297             var file = new FileInfo(filePath);
298             if (file.Exists)
299             {
300                 errorMess = null;
301                 return true;
302             }
303             errorMess = "文件不存在";
304             return false;
305         }
306 
307         /// <summary>
308         ///     是否Excel2003
309         /// </summary>
310         /// <param name="filePath"></param>
311         /// <returns></returns>
312         private static bool IsExcel2003(string filePath)
313         {
314             return IsMatch("^.+\\.(?i)(xls)$", filePath);
315         }
316 
317         /// <summary>
318         ///     是否Excel2007
319         /// </summary>
320         /// <param name="filePath"></param>
321         /// <returns></returns>
322         private static bool IsExcel2007(string filePath)
323         {
324             return IsMatch("^.+\\.(?i)(xlsx)$", filePath);
325         }
326 
327         /// <summary>
328         ///     正则匹配
329         /// </summary>
330         /// <param name="pattern"></param>
331         /// <param name="input"></param>
332         /// <returns></returns>
333         private static bool IsMatch(string pattern, string input)
334         {
335             var regex = new Regex(pattern);
336             return regex.IsMatch(input);
337         }
338 
339     }
340 }

 

posted @ 2016-09-25 15:04  hibity  阅读(1034)  评论(0编辑  收藏  举报