原文url:http://www.cnblogs.com/wolf-sun/p/3589605.html
引言
项目中常用到将数据导入Excel,将Excel中的数据导入数据库的功能,曾经也查找过相关的内容,将曾经用过的方案总结一下。
方案一
NPOI
NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。
使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。NPOI是构建在POI 3.x版本之上的,它可以在没有安装Office的情况下对Word/Excel文档进行读写操作。
优势
(一)传统操作Excel遇到的问题:
1、如果是.NET,需要在服务器端装Office,且及时更新它,以防漏洞,还需要设定权限允许.NET访问COM+,如果在导出过程中出问题可能导致服务器宕机。
2、Excel会把只包含数字的列进行类型转换,本来是文本型的,Excel会将其转成数值型的,比如编号000123会变成123。
3、导出时,如果字段内容以“-”或“=”开头,Excel会把它当成公式进行,会报错。
4、Excel会根据Excel文件前8行分析数据类型,如果正好你前8行某一列只是数字,那它会认为该列为数值型,自动将该列转变成类似1.42702E+17格式,日期列变成包含日期和数字的。
(二)使用NPOI的优势
1、您可以完全免费使用该框架
2、包含了大部分EXCEL的特性(单元格样式、数据格式、公式等等)
3、专业的技术支持服务(24*7全天候) (非免费)
4、支持处理的文件格式包括xls, xlsx, docx.
5、采用面向接口的设计架构( 可以查看 NPOI.SS 的命名空间)
6、同时支持文件的导入和导出
7、基于.net 2.0 也支持xlsx 和 docx格式(当然也支持.net 4.0)
8、来自全世界大量成功且真实的测试Cases
9、大量的实例代码
11、你不需要在服务器上安装微软的Office,可以避免版权问题。
12、使用起来比Office PIA的API更加方便,更人性化。
13、你不用去花大力气维护NPOI,NPOI Team会不断更新、改善NPOI,绝对省成本。
NPOI
之所以强大,并不是因为它支持导出Excel,而是因为它支持导入Excel,并能“理解”OLE2文档结构,这也是其他一些Excel读写库比较弱的方
面。通常,读入并理解结构远比导出来得复杂,因为导入你必须假设一切情况都是可能的,而生成你只要保证满足你自己需求就可以了,如果把导入需求和生成需求
比做两个集合,那么生成需求通常都是导入需求的子集,这一规律不仅体现在Excel读写库中,也体现在pdf读写库中,目前市面上大部分的pdf库仅支持
生成,不支持导入。
构成
NPOI 1.2.x主要由POIFS、DDF、HPSF、HSSF、SS、Util六部分组成。
|
NPOI.POIFS
|
OLE2/ActiveX文档属性读写库
|
|
NPOI.DDF
|
Microsoft Office Drawing读写库
|
|
NPOI.HPSF
|
OLE2/ActiveX文档读写库
|
|
NPOI.HSSF
|
Microsoft Excel BIFF(Excel 97-2003)格式读写库
|
|
NPOI.SS
|
Excel公用接口及Excel公式计算引擎
|
|
NPOI.Util
|
基础类库,提供了很多实用功能,可用于其他读写文件格式项目的开发
|
| Assembly名称 | 模块/命名空间 | 说明 |
| NPOI.DLL |
NPOI.POIFS
|
OLE2/ActiveX文档属性读写库
|
| NPOI.DLL |
NPOI.DDF
|
微软Office Drawing读写库
|
| NPOI.DLL |
NPOI.HPSF
|
OLE2/ActiveX文档读写库
|
| NPOI.DLL |
NPOI.HSSF
|
微软Excel BIFF(Excel 97-2003, doc)格式读写库
|
| NPOI.DLL |
NPOI.SS
|
Excel公用接口及Excel公式计算引擎
|
| NPOI.DLL |
NPOI.Util
|
基础类库,提供了很多实用功能,可用于其他读写文件格式项目的开发
|
| NPOI.OOXML.DLL | NPOI.XSSF | Excel 2007(xlsx)格式读写库 |
| NPOI.OOXML.DLL | NPOI.XWPF | Word 2007(docx)格式读写库 |
| NPOI.OpenXml4Net.DLL | NPOI.OpenXml4Net | OpenXml底层zip包读写库 |
| NPOI.OpenXmlFormats.DLL | NPOI.OpenXmlFormats | 微软Office OpenXml对象关系库 |
(以上内容来自百度百科)从上表可知NPOI组件已支持excel2007,记得之前用的时候只支持excel2003。很久没研究过这玩意儿了。
案例
官网地址:http://npoi.codeplex.com/,可以从官网下载NPOI2.X版本的。
首先引入
ICSharpCode.SharpZipLib.dll
NPOI.dll
NPOI.OOXML.dll
NPOI.OpenXml4Net.dll
NPOI.OpenXmlFormats.dll
然后引入命名空间:
using NPOI.XSSF.UserModel; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel;
辅助类
using NPOI.XSSF.UserModel; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using NPOI.SS.Formula.Eval; namespace Wolfy.Common { /// <summary> /// 使用NPOI组件 /// 需引入ICSharpCode.SharpZipLib.dll/NPOI.dll/NPOI.OOXML.dll/NPOI.OpenXml4Net.dll/NPOI.OpenXmlFormats.dll /// office2007 /// </summary> public class NPOIExcelHelper { /// <summary> /// 将Excel文件中的数据读出到DataTable中 /// </summary> /// <param name="file"></param> /// <returns></returns> public static DataTable Excel2DataTable(string file, string sheetName, string tableName) { DataTable dt = new DataTable(); IWorkbook workbook = null; using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) { //office2003 HSSFWorkbook workbook = new XSSFWorkbook(fs); } ISheet sheet = workbook.GetSheet(sheetName); dt = Export2DataTable(sheet, 0, true); return dt; } /// <summary> /// 将指定sheet中的数据导入到datatable中 /// </summary> /// <param name="sheet">指定需要导出的sheet</param> /// <param name="HeaderRowIndex">列头所在的行号,-1没有列头</param> /// <param name="needHeader"></param> /// <returns></returns> private static DataTable Export2DataTable(ISheet sheet, int HeaderRowIndex, bool needHeader) { DataTable dt = new DataTable(); XSSFRow headerRow = null; int cellCount; try { if (HeaderRowIndex < 0 || !needHeader) { headerRow = sheet.GetRow(0) as XSSFRow; cellCount = headerRow.LastCellNum; for (int i = headerRow.FirstCellNum; i <= cellCount; i++) { DataColumn column = new DataColumn(Convert.ToString(i)); dt.Columns.Add(column); } } else { headerRow = sheet.GetRow(HeaderRowIndex) as XSSFRow; cellCount = headerRow.LastCellNum; for (int i = headerRow.FirstCellNum; i <= cellCount; i++) { ICell cell = headerRow.GetCell(i); if (cell == null) { break;//到最后 跳出循环 } else { DataColumn column = new DataColumn(headerRow.GetCell(i).ToString()); dt.Columns.Add(column); } } } int rowCount = sheet.LastRowNum; for (int i = HeaderRowIndex + 1; i <= sheet.LastRowNum; i++) { XSSFRow row = null; if (sheet.GetRow(i) == null) { row = sheet.CreateRow(i) as XSSFRow; } else { row = sheet.GetRow(i) as XSSFRow; } DataRow dtRow = dt.NewRow(); for (int j = row.FirstCellNum; j <= cellCount; j++) { if (row.GetCell(j) != null) { switch (row.GetCell(j).CellType) { case CellType.Boolean: dtRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue); break; case CellType.Error: dtRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue); break; case CellType.Formula: switch (row.GetCell(j).CachedFormulaResultType) { case CellType.Boolean: dtRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue); break; case CellType.Error: dtRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue); break; case CellType.Numeric: dtRow[j] = Convert.ToString(row.GetCell(j).NumericCellValue); break; case CellType.String: string strFORMULA = row.GetCell(j).StringCellValue; if (strFORMULA != null && strFORMULA.Length > 0) { dtRow[j] = strFORMULA.ToString(); } else { dtRow[j] = null; } break; default: dtRow[j] = ""; break; } break; case CellType.Numeric: if (DateUtil.IsCellDateFormatted(row.GetCell(j))) { dtRow[j] = DateTime.FromOADate(row.GetCell(j).NumericCellValue); } else { dtRow[j] = Convert.ToDouble(row.GetCell(j).NumericCellValue); } break; case CellType.String: string str = row.GetCell(j).StringCellValue; if (!string.IsNullOrEmpty(str)) { dtRow[j] = Convert.ToString(str); } else { dtRow[j] = null; } break; default: dtRow[j] = ""; break; } } } dt.Rows.Add(dtRow); } } catch (Exception) { return null; } return dt; } /// <summary> /// 将DataTable中的数据导入Excel文件中 /// </summary> /// <param name="dt"></param> /// <param name="file"></param> public static void DataTable2Excel(DataTable dt, string file, string sheetName) { IWorkbook workbook = new XSSFWorkbook(); ISheet sheet = workbook.CreateSheet(sheetName); IRow header = sheet.CreateRow(0); for (int i = 0; i < dt.Columns.Count; i++) { ICell cell = header.CreateCell(i); cell.SetCellValue(dt.Columns[i].ColumnName); } //数据 for (int i = 0; i < dt.Rows.Count; i++) { IRow row = sheet.CreateRow(i + 1); for (int j = 0; j < dt.Columns.Count; j++) { ICell cell = row.CreateCell(j); cell.SetCellValue(dt.Rows[i][j].ToString()); } } MemoryStream stream = new MemoryStream(); workbook.Write(stream); byte[] buffer = stream.ToArray(); using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write)) { fs.Write(buffer, 0, buffer.Length); fs.Flush(); } } /// <summary> /// 获取单元格类型 /// </summary> /// <param name="cell"></param> /// <returns></returns> private static object GetValueType(XSSFCell cell) { if (cell == null) { return null; } switch (cell.CellType) { case CellType.Blank: return null; case CellType.Boolean: return cell.BooleanCellValue; case CellType.Error: return cell.ErrorCellValue; case CellType.Numeric: return cell.NumericCellValue; case CellType.String: return cell.StringCellValue; case CellType.Formula: default: return "=" + cell.StringCellValue; } } } }
参考:http://www.cnblogs.com/Joetao/articles/3247909.html
测试结果
导入Excel,student.xlsx
导入DataTable,这里只将数据导入DataTable,导入数据库部分,就不再写了。
测试数据,向qq群里一朋友要的。大概有5w多条,lz机子是老爷机跑不起,只导出了其中的1k条。
方案二
利用office的com组件
首先添加com引用
引入命名空间
using Excel = Microsoft.Office.Interop.Excel;
Com操作Excel辅助类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Excel = Microsoft.Office.Interop.Excel; using System.Web.UI; using System.Web; using System.Data; namespace Wolfy.Common { /// <summary> /// 使用com组件 操作Excel /// </summary> public class ComExcelHelper { private Excel.Application appExcel = null; private Excel.Workbook workbook = null; private Excel.Worksheet sheet = null; private DateTime dtBefore; private DateTime dtAfter; private string filePath; public string FilePath { get { return filePath; } set { filePath = value; } } private string timestamp; /// <summary> /// 以时间字符串作为保存文件的名称 /// </summary> public string Timestamp { get { return timestamp; } set { timestamp = value; } } private object mValue = System.Reflection.Missing.Value; /// <summary> ///是否打开Excel界面 /// </summary> public bool Visible { set { appExcel.Visible = value; } } public ComExcelHelper() { this.dtBefore = DateTime.Now; appExcel = new Excel.Application(); this.dtAfter = DateTime.Now; this.timestamp = DateTime.Now.ToShortDateString().Replace("-", "") + DateTime.Now.ToShortDateString().Replace("-", "") + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString(); } public ComExcelHelper(string strFilePath) { this.dtBefore = DateTime.Now; appExcel = new Excel.Application(); this.dtAfter = DateTime.Now; this.workbook = (Excel.Workbook)appExcel.Workbooks.Open(strFilePath, mValue, false, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue); this.timestamp = DateTime.Now.ToShortDateString().Replace("-", "") + DateTime.Now.ToShortDateString().Replace("-", "") + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString(); } public void Dispose() { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(sheet); sheet = null; workbook.Close(false, mValue, mValue); System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook); workbook = null; appExcel.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(appExcel); appExcel = null; GC.Collect(); GC.WaitForPendingFinalizers(); } catch (Exception ex) { throw ex; } finally { foreach (System.Diagnostics.Process pro in System.Diagnostics.Process.GetProcessesByName("Excel")) { if (pro.StartTime > this.dtBefore && pro.StartTime < this.dtAfter) { pro.Kill(); } } } System.GC.SuppressFinalize(this); } /// <summary> /// 加载Excel /// </summary> public void Load() { if (workbook == null && this.filePath != null) { workbook = appExcel.Workbooks.Open(this.filePath, mValue, false, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue); } } /// <summary> /// 加载Excel /// </summary> public void Load(string strFilePath) { if (workbook == null) { workbook = appExcel.Workbooks.Open(strFilePath, mValue, false, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue); } } /// <summary> /// 新建工作表 /// </summary> /// <param name="sheetName"></param> public void NewWorkSheet(string sheetName) { sheet = workbook.Sheets.Add(workbook.Sheets[1], mValue, mValue, mValue); sheet.Name = sheetName; } /// <summary> /// 在指定的单元格插入指定的值 /// </summary> /// <param name="strCell">单元格 如"A4"</param> /// <param name="objValue">文本 数字等值</param> public void WriteCell(string strCell, object objValue) { sheet.get_Range(strCell, mValue).Value2 = objValue; } /// <summary> /// 在指定Range中插入指定的值 /// </summary> /// <param name="strStartCell">Range的开始单元格</param> /// <param name="strEndCell">Range的结束单元格</param> /// <param name="objValue">文本、数字等值</param> public void WriteRange(string strStartCell, string strEndCell, object objValue) { sheet.get_Range(strStartCell, strEndCell).Value2 = objValue; } /**/ /// <summary> /// 合并单元格,并在合并后的单元格中插入指定的值 /// </summary> /// <param name="strStartCell"></param> /// <param name="strEndCell"></param> /// <param name="objValue"></param> public void WriteAfterMerge(string strStartCell, string strEndCell, object objValue) { sheet.get_Range(strStartCell, strEndCell).Merge(mValue); sheet.get_Range(strStartCell, mValue).Value2 = objValue; } /**/ /// <summary> /// 在连续单元格中插入一个DataTable中的值 /// </summary> /// <param name="strStartCell">开始的单元格</param> /// <param name="dtData">存储数据的DataTable</param> public void WriteTable(string strStartCell, System.Data.DataTable dtData) { object[,] arrData = new object[dtData.Rows.Count, dtData.Columns.Count]; for (int i = 0; i < dtData.Rows.Count; i++) for (int j = 0; j < dtData.Columns.Count; j++) arrData[i, j] = dtData.Rows[i][j]; sheet.get_Range(strStartCell, this.GetEndCell(strStartCell, dtData.Rows.Count - 1, dtData.Columns.Count - 1)).Value2 = arrData; arrData = null; } /**/ /// <summary> /// 在连续单元格中插入一个DataTable并作超级链接 /// </summary> /// <param name="strStartCell">起始单元格标识符</param> /// <param name="dtData">存储数据的DataTable</param> /// <param name="strLinkField">链接的地址字段</param> /// <param name="strTextField">链接的文本字段</param> public void WriteTableAndLink(string strStartCell, System.Data.DataTable dtData, string strLinkField, string strTextField) { object[,] arrData = new object[dtData.Rows.Count, dtData.Columns.Count - 1]; for (int i = 0; i < dtData.Rows.Count; i++) { for (int j = 0; j < dtData.Columns.Count; j++) { if (j > dtData.Columns.IndexOf(strLinkField)) arrData[i, j - 1] = dtData.Rows[i][j]; else if (j < dtData.Columns.IndexOf(strLinkField)) arrData[i, j] = dtData.Rows[i][j]; } } sheet.get_Range(strStartCell, this.GetEndCell(strStartCell, dtData.Rows.Count - 1, dtData.Columns.Count - 2)).Value2 = arrData; for (int i = 0; i < dtData.Rows.Count; i++) this.AddHyperLink(this.NtoL(this.LtoN(this.GetCellLetter(strStartCell)) + dtData.Columns.IndexOf(strTextField)) + System.Convert.ToString(this.GetCellNumber(strStartCell) + i), dtData.Rows[i][strLinkField].ToString() + ".htm", "点击查看详细", dtData.Rows[i][strTextField].ToString()); arrData = null; } /**/ /// <summary> /// 为单元格设置公式 /// </summary> /// <param name="strCell">单元格标识符</param> /// <param name="strFormula">公式</param> public void SetFormula(string strCell, string strFormula) { sheet.get_Range(strCell, mValue).Formula = strFormula; } /**/ /// <summary> /// 设置单元格或连续区域的字体为黑体 /// </summary> /// <param name="strCell">单元格标识符</param> public void SetBold(string strCell) { sheet.get_Range(strCell, mValue).Font.Bold = true; } /**/ /// <summary> /// 设置连续区域的字体为黑体 /// </summary> /// <param name="strStartCell">开始单元格标识符</param> /// <param name="strEndCell">结束单元格标识符</param> public void SetBold(string strStartCell, string strEndCell) { sheet.get_Range(strStartCell, strEndCell).Font.Bold = true; } /**/ /// <summary> /// 设置单元格或连续区域的字体颜色 /// </summary> /// <param name="strCell">单元格标识符</param> /// <param name="clrColor">颜色</param> public void SetColor(string strCell, System.Drawing.Color clrColor) { sheet.get_Range(strCell, mValue).Font.Color = System.Drawing.ColorTranslator.ToOle(clrColor); } /**/ /// <summary> /// 设置连续区域的字体颜色 /// </summary> /// <param name="strStartCell">开始单元格标识符</param> /// <param name="strEndCell">结束单元格标识符</param> /// <param name="clrColor">颜色</param> public void SetColor(string strStartCell, string strEndCell, System.Drawing.Color clrColor) { sheet.get_Range(strStartCell, strEndCell).Font.Color = System.Drawing.ColorTranslator.ToOle(clrColor); } /**/ /// <summary> /// 设置单元格或连续区域的边框:上下左右都为黑色连续边框 /// </summary> /// <param name="strCell">单元格标识符</param> public void SetBorderAll(string strCell) { sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlEdgeTop].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlEdgeTop].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlEdgeBottom].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlEdgeBottom].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlEdgeLeft].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlEdgeLeft].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlEdgeRight].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlEdgeRight].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlInsideHorizontal].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlInsideHorizontal].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlInsideVertical].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strCell, mValue).Borders[Excel.XlBordersIndex.xlInsideVertical].LineStyle = Excel.XlLineStyle.xlContinuous; } /**/ /// <summary> /// 设置连续区域的边框:上下左右都为黑色连续边框 /// </summary> /// <param name="strStartCell">开始单元格标识符</param> /// <param name="strEndCell">结束单元格标识符</param> public void SetBorderAll(string strStartCell, string strEndCell) { sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlEdgeTop].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlEdgeTop].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlEdgeBottom].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlEdgeBottom].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlEdgeLeft].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlEdgeLeft].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlEdgeRight].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlEdgeRight].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlInsideHorizontal].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlInsideHorizontal].LineStyle = Excel.XlLineStyle.xlContinuous; sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlInsideVertical].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); sheet.get_Range(strStartCell, strEndCell).Borders[Excel.XlBordersIndex.xlInsideVertical].LineStyle = Excel.XlLineStyle.xlContinuous; } /**/ /// <summary> /// 设置单元格或连续区域水平居左 /// </summary> /// <param name="strCell">单元格标识符</param> public void SetHAlignLeft(string strCell) { sheet.get_Range(strCell, mValue).HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft; } /**/ /// <summary> /// 设置连续区域水平居左 /// </summary> /// <param name="strStartCell">开始单元格标识符</param> /// <param name="strEndCell">结束单元格标识符</param> public void SetHAlignLeft(string strStartCell, string strEndCell) { sheet.get_Range(strStartCell, strEndCell).HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft; } /**/ /// <summary> /// 设置单元格或连续区域水平居左 /// </summary> /// <param name="strCell">单元格标识符</param> public void SetHAlignCenter(string strCell) { sheet.get_Range(strCell, mValue).HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter; } /**/ /// <summary> /// 设置连续区域水平居中 /// </summary> /// <param name="strStartCell">开始单元格标识符</param> /// <param name="strEndCell">结束单元格标识符</param> public void SetHAlignCenter(string strStartCell, string strEndCell) { sheet.get_Range(strStartCell, strEndCell).HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter; } /**/ /// <summary> /// 设置单元格或连续区域水平居右 /// </summary> /// <param name="strCell">单元格标识符</param> public void SetHAlignRight(string strCell) { sheet.get_Range(strCell, mValue).HorizontalAlignment = Excel.XlHAlign.xlHAlignRight; } /**/ /// <summary> /// 设置连续区域水平居右 /// </summary> /// <param name="strStartCell">开始单元格标识符</param> /// <param name="strEndCell">结束单元格标识符</param> public void SetHAlignRight(string strStartCell, string strEndCell) { sheet.get_Range(strStartCell, strEndCell).HorizontalAlignment = Excel.XlHAlign.xlHAlignRight; } /**/ /// <summary> /// 设置单元格或连续区域的显示格式 /// </summary> /// <param name="strCell">单元格标识符</param> /// <param name="strNF">如"#,##0.00"的显示格式</param> public void SetNumberFormat(string strCell, string strNF) { sheet.get_Range(strCell, mValue).NumberFormat = strNF; } /**/ /// <summary> /// 设置连续区域的显示格式 /// </summary> /// <param name="strStartCell">开始单元格标识符</param> /// <param name="strEndCell">结束单元格标识符</param> /// <param name="strNF">如"#,##0.00"的显示格式</param> public void SetNumberFormat(string strStartCell, string strEndCell, string strNF) { sheet.get_Range(strStartCell, strEndCell).NumberFormat = strNF; } /**/ /// <summary> /// 设置单元格或连续区域的字体大小 /// </summary> /// <param name="strCell">单元格或连续区域标识符</param> /// <param name="intFontSize"></param> public void SetFontSize(string strCell, int intFontSize) { sheet.get_Range(strCell, mValue).Font.Size = intFontSize.ToString(); } /**/ /// <summary> /// 设置连续区域的字体大小 /// </summary> /// <param name="strStartCell">开始单元格标识符</param> /// <param name="strEndCell">结束单元格标识符</param> /// <param name="intFontSize">字体大小</param> public void SetFontSize(string strStartCell, string strEndCell, int intFontSize) { sheet.get_Range(strStartCell, strEndCell).Font.Size = intFontSize.ToString(); } /**/ /// <summary> /// 设置列宽 /// </summary> /// <param name="strColID">列标识,如A代表第一列</param> /// <param name="decWidth">宽度</param> public void SetColumnWidth(string strColID, double dblWidth) { ((Excel.Range)sheet.Columns.GetType().InvokeMember("Item", System.Reflection.BindingFlags.GetProperty, null, sheet.Columns, new object[] { (strColID + ":" + strColID).ToString() })).ColumnWidth = dblWidth; } /**/ /// <summary> /// 为单元格添加超级链接 /// </summary> /// <param name="strCell">单元格标识符</param> /// <param name="strAddress">链接地址</param> /// <param name="strTip">屏幕提示</param> /// <param name="strText">链接文本</param> public void AddHyperLink(string strCell, string strAddress, string strTip, string strText) { sheet.Hyperlinks.Add(sheet.get_Range(strCell, mValue), strAddress, mValue, strTip, strText); } /**/ /// <summary> /// 已知开始的单元格标识,求intR行、intColumn列后的单元格标识 /// </summary> /// <param name="strStartCell">开始单元格标识</param> /// <param name="intR">行数</param> /// <param name="intC">列数</param> /// <returns>单元格标识符结果</returns> public string GetEndCell(string strStartCell, int intR, int intC) { string endcell = string.Empty; System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"^(?<vLetter>[A-Z]+)(?<vNumber>\d+)"); if (regex.IsMatch(strStartCell)) { endcell = this.NtoL(this.LtoN(regex.Match(strStartCell).Result("${vLetter}")) + intC) + System.Convert.ToString((System.Convert.ToInt32(regex.Match(strStartCell).Result("${vNumber}")) + intR)); } return endcell; } /**/ /// <summary> /// 获取单元格标识符中的字母 /// </summary> /// <param name="strCell">单元格标识符</param> /// <returns>单元格标识符对应的字母</returns> public string GetCellLetter(string strCell) { System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"^(?<vLetter>[A-Z]+)(?<vNumber>\d+)"); return regex.Match(strCell).Result("${vLetter}"); } /**/ /// <summary> /// 获取单元格标识符中的数字 /// </summary> /// <param name="strCell">单元格标识符</param> public int GetCellNumber(string strCell) { System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"^(?<vLetter>[A-Z]+)(?<vNumber>\d+)"); return System.Convert.ToInt32(regex.Match(strCell).Result("${vNumber}")); } /**/ /// <summary> /// 另存为xls文件 /// </summary> /// <param name="strFilePath">文件路径</param> public void SaveAs(string strFilePath) { workbook.SaveCopyAs(strFilePath); } /**/ /// <summary> /// 另存为xls文件 /// </summary> /// <param name="strFilePath">文件路径</param> public void Save() { workbook.Save(); } /// <summary> /// 将Excel中的数据 读入DataTable中 /// </summary> /// <param name="filePath">excel文件的路径</param> /// <param name="dtName">datatable的名字</param> /// <param name="headName">表头,以逗号分隔</param> /// <returns></returns> public DataTable ReadExcel2DataTable(string filePath, string dtName, string headName) { workbook = this.appExcel.Workbooks.Open(filePath, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue, mValue); sheet = workbook.Worksheets.get_Item(1); DataTable dt = new DataTable(dtName); string[] heads = !string.IsNullOrEmpty(headName) ? headName.Split(',') : null; if (heads != null) { for (int i = 0; i < heads.Length; i++) { DataColumn column = new DataColumn(heads[i]); //这里没对类型 进行处理 dt.Columns.Add(column); } for (int i = 0; i <= sheet.UsedRange.Rows.Count; i++) { DataRow dr = dt.NewRow(); for (int j = 0; j < heads.Length; j++) { string cellString = NtoL(j + 1); dr[heads[j]] = sheet.get_Range(cellString + (i + 1)).Value2; } dt.Rows.Add(dr); } } else { for (int i = 0; i <= sheet.UsedRange.Rows.Count; i++) { DataRow dr = dt.NewRow(); for (int j = 0; j <= sheet.UsedRange.Columns.Count; j++) { dr[j + 1] = sheet.get_Range(NtoL(j + 1) + (i + 1)).Value2; } dt.Rows.Add(dr); } } return dt; } /**/ /// <summary> /// 另存为html文件 /// </summary> /// <param name="strFilePath">文件路径</param> public void SaveHtml(string strFilePath) { workbook.SaveAs(strFilePath, Excel.XlFileFormat.xlHtml, mValue, mValue, mValue, mValue, Excel.XlSaveAsAccessMode.xlNoChange, mValue, mValue, mValue, mValue, mValue); } public void CreateHtmlFile() { } /**/ /// <summary> /// 字母转换为数字,Excel列头,如A-1;AA-27 /// </summary> /// <param name="strLetter">字母</param> /// <returns>字母对应的数字</returns> private int LtoN(string strLetter) { int intRtn = 0; string strLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (strLetter.Length == 2) intRtn += (strLetters.IndexOf(strLetter.Substring(0, 1)) + 1) * 26; intRtn += strLetters.IndexOf(strLetter.Substring(strLetter.Length - 1, 1)) + 1; return intRtn; } /**/ /// <summary> /// 数字转换为字母,Excel列头,如1-A;27-AA /// </summary> /// <param name="intNumber">数字</param> /// <returns>数字对应的字母</returns> private string NtoL(int intNumber) { if (intNumber > 702) return String.Empty; if (intNumber == 702) return "ZZ"; string strRtn = String.Empty; string strLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (intNumber > 26) strRtn = strLetters.Substring(intNumber / 26 - 1, 1); strRtn += strLetters.Substring((intNumber % 26) - 1, 1); return strRtn; } } }