引言
项目中常用到将数据导入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, , 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 < || !needHeader)
{
headerRow = sheet.GetRow() 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 + ; 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 > )
{
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();
for (int i = ; i < dt.Columns.Count; i++)
{
ICell cell = header.CreateCell(i);
cell.SetCellValue(dt.Columns[i].ColumnName);
}
//数据
for (int i = ; i < dt.Rows.Count; i++)
{
IRow row = sheet.CreateRow(i + );
for (int j = ; 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, , 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;
}
} }
}
NPOIExcelHelper
参考: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[], 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 = ; i < dtData.Rows.Count; i++)
for (int j = ; j < dtData.Columns.Count; j++)
arrData[i, j] = dtData.Rows[i][j]; sheet.get_Range(strStartCell, this.GetEndCell(strStartCell, dtData.Rows.Count - , dtData.Columns.Count - )).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 - ]; for (int i = ; i < dtData.Rows.Count; i++)
{
for (int j = ; j < dtData.Columns.Count; j++)
{
if (j > dtData.Columns.IndexOf(strLinkField))
arrData[i, j - ] = 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 - , dtData.Columns.Count - )).Value2 = arrData; for (int i = ; 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();
DataTable dt = new DataTable(dtName);
string[] heads = !string.IsNullOrEmpty(headName) ? headName.Split(',') : null;
if (heads != null)
{
for (int i = ; i < heads.Length; i++)
{
DataColumn column = new DataColumn(heads[i]);
//这里没对类型 进行处理
dt.Columns.Add(column);
}
for (int i = ; i <= sheet.UsedRange.Rows.Count; i++)
{
DataRow dr = dt.NewRow();
for (int j = ; j < heads.Length; j++)
{
string cellString = NtoL(j + );
dr[heads[j]] = sheet.get_Range(cellString + (i + )).Value2; }
dt.Rows.Add(dr); }
}
else
{
for (int i = ; i <= sheet.UsedRange.Rows.Count; i++)
{
DataRow dr = dt.NewRow();
for (int j = ; j <= sheet.UsedRange.Columns.Count; j++)
{
dr[j + ] = sheet.get_Range(NtoL(j + ) + (i + )).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 = ; string strLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (strLetter.Length == )
intRtn += (strLetters.IndexOf(strLetter.Substring(, )) + ) * ; intRtn += strLetters.IndexOf(strLetter.Substring(strLetter.Length - , )) + ; return intRtn; } /**/
/// <summary>
/// 数字转换为字母,Excel列头,如1-A;27-AA
/// </summary>
/// <param name="intNumber">数字</param>
/// <returns>数字对应的字母</returns>
private string NtoL(int intNumber)
{
if (intNumber > )
return String.Empty; if (intNumber == )
return "ZZ"; string strRtn = String.Empty; string strLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (intNumber > )
strRtn = strLetters.Substring(intNumber / - , ); strRtn += strLetters.Substring((intNumber % ) - , ); return strRtn;
} }
}
ComExcelHelper
参考:http://www.cnblogs.com/waxdoll/archive/2005/10/28/264071.html
DataTable导入Excel
Excel读入DataTable
这里未对类型进行处理,datetime类型的数据会转换成数值类型的
方案三
将Excel数据表当作数据源,通过 OleDb来实现。
同样需要引入Microsoft Excel 14.0 Object Library
分享一个操作类:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls; namespace Wolfy.Common
{
class OleDbExcelHelper
{
#region 数据导出至Excel文件
/// </summary>
/// 导出Excel文件,自动返回可下载的文件流
/// </summary>
public static void DataTable1Excel(System.Data.DataTable dtData)
{
GridView gvExport = null;
HttpContext curContext = HttpContext.Current;
StringWriter strWriter = null;
HtmlTextWriter htmlWriter = null;
if (dtData != null)
{
curContext.Response.ContentType = "application/vnd.ms-excel";
curContext.Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
curContext.Response.Charset = "utf-8";
strWriter = new StringWriter();
htmlWriter = new HtmlTextWriter(strWriter);
gvExport = new GridView();
gvExport.DataSource = dtData.DefaultView;
gvExport.AllowPaging = false;
gvExport.DataBind();
gvExport.RenderControl(htmlWriter);
curContext.Response.Write("<meta http-equiv=\"Content-Type\" content=\"text/html;charset=gb2312\"/>" + strWriter.ToString());
curContext.Response.End();
}
} /// <summary>
/// 导出Excel文件,转换为可读模式
/// </summary>
public static void DataTable2Excel(System.Data.DataTable dtData)
{
DataGrid dgExport = null;
HttpContext curContext = HttpContext.Current;
StringWriter strWriter = null;
HtmlTextWriter htmlWriter = null; if (dtData != null)
{
curContext.Response.ContentType = "application/vnd.ms-excel";
curContext.Response.ContentEncoding = System.Text.Encoding.UTF8;
curContext.Response.Charset = "";
strWriter = new StringWriter();
htmlWriter = new HtmlTextWriter(strWriter);
dgExport = new DataGrid();
dgExport.DataSource = dtData.DefaultView;
dgExport.AllowPaging = false;
dgExport.DataBind();
dgExport.RenderControl(htmlWriter);
curContext.Response.Write(strWriter.ToString());
curContext.Response.End();
}
} /// <summary>
/// 导出Excel文件,并自定义文件名
/// </summary>
public static void DataTable3Excel(System.Data.DataTable dtData, String FileName)
{
GridView dgExport = null;
HttpContext curContext = HttpContext.Current;
StringWriter strWriter = null;
HtmlTextWriter htmlWriter = null; if (dtData != null)
{
HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8);
curContext.Response.AddHeader("content-disposition", "attachment;filename=" + HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8) + ".xls");
curContext.Response.ContentType = "application nd.ms-excel";
curContext.Response.ContentEncoding = System.Text.Encoding.UTF8;
curContext.Response.Charset = "GB2312";
strWriter = new StringWriter();
htmlWriter = new HtmlTextWriter(strWriter);
dgExport = new GridView();
dgExport.DataSource = dtData.DefaultView;
dgExport.AllowPaging = false;
dgExport.DataBind();
dgExport.RenderControl(htmlWriter);
curContext.Response.Write(strWriter.ToString());
curContext.Response.End();
}
} /// <summary>
/// 将数据导出至Excel文件
/// </summary>
/// <param name="Table">DataTable对象</param>
/// <param name="ExcelFilePath">Excel文件路径</param>
public static bool OutputToExcel(System.Data.DataTable Table, string ExcelFilePath)
{
if (File.Exists(ExcelFilePath))
{
throw new Exception("该文件已经存在!");
} if ((Table.TableName.Trim().Length == ) || (Table.TableName.ToLower() == "table"))
{
Table.TableName = "Sheet1";
} //数据表的列数
int ColCount = Table.Columns.Count; //用于记数,实例化参数时的序号
int i = ; //创建参数
OleDbParameter[] para = new OleDbParameter[ColCount]; //创建表结构的SQL语句
string TableStructStr = @"Create Table " + Table.TableName + "("; //连接字符串
string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 8.0;";
OleDbConnection objConn = new OleDbConnection(connString); //创建表结构
OleDbCommand objCmd = new OleDbCommand(); //数据类型集合
ArrayList DataTypeList = new ArrayList();
DataTypeList.Add("System.Decimal");
DataTypeList.Add("System.Double");
DataTypeList.Add("System.Int16");
DataTypeList.Add("System.Int32");
DataTypeList.Add("System.Int64");
DataTypeList.Add("System.Single"); //遍历数据表的所有列,用于创建表结构
foreach (DataColumn col in Table.Columns)
{
//如果列属于数字列,则设置该列的数据类型为double
if (DataTypeList.IndexOf(col.DataType.ToString()) >= )
{
para[i] = new OleDbParameter("@" + col.ColumnName, OleDbType.Double);
objCmd.Parameters.Add(para[i]); //如果是最后一列
if (i + == ColCount)
{
TableStructStr += col.ColumnName + " double)";
}
else
{
TableStructStr += col.ColumnName + " double,";
}
}
else
{
para[i] = new OleDbParameter("@" + col.ColumnName, OleDbType.VarChar);
objCmd.Parameters.Add(para[i]); //如果是最后一列
if (i + == ColCount)
{
TableStructStr += col.ColumnName + " varchar)";
}
else
{
TableStructStr += col.ColumnName + " varchar,";
}
}
i++;
} //创建Excel文件及文件结构
try
{
objCmd.Connection = objConn;
objCmd.CommandText = TableStructStr; if (objConn.State == ConnectionState.Closed)
{
objConn.Open();
}
objCmd.ExecuteNonQuery();
}
catch (Exception exp)
{
throw exp;
} //插入记录的SQL语句
string InsertSql_1 = "Insert into " + Table.TableName + " (";
string InsertSql_2 = " Values (";
string InsertSql = ""; //遍历所有列,用于插入记录,在此创建插入记录的SQL语句
for (int colID = ; colID < ColCount; colID++)
{
if (colID + == ColCount) //最后一列
{
InsertSql_1 += Table.Columns[colID].ColumnName + ")";
InsertSql_2 += "@" + Table.Columns[colID].ColumnName + ")";
}
else
{
InsertSql_1 += Table.Columns[colID].ColumnName + ",";
InsertSql_2 += "@" + Table.Columns[colID].ColumnName + ",";
}
} InsertSql = InsertSql_1 + InsertSql_2; //遍历数据表的所有数据行
for (int rowID = ; rowID < Table.Rows.Count; rowID++)
{
for (int colID = ; colID < ColCount; colID++)
{
if (para[colID].DbType == DbType.Double && Table.Rows[rowID][colID].ToString().Trim() == "")
{
para[colID].Value = ;
}
else
{
para[colID].Value = Table.Rows[rowID][colID].ToString().Trim();
}
}
try
{
objCmd.CommandText = InsertSql;
objCmd.ExecuteNonQuery();
}
catch (Exception exp)
{
string str = exp.Message;
}
}
try
{
if (objConn.State == ConnectionState.Open)
{
objConn.Close();
}
}
catch (Exception exp)
{
throw exp;
}
return true;
} /// <summary>
/// 将数据导出至Excel文件
/// </summary>
/// <param name="Table">DataTable对象</param>
/// <param name="Columns">要导出的数据列集合</param>
/// <param name="ExcelFilePath">Excel文件路径</param>
public static bool OutputToExcel(System.Data.DataTable Table, ArrayList Columns, string ExcelFilePath)
{
if (File.Exists(ExcelFilePath))
{
throw new Exception("该文件已经存在!");
} //如果数据列数大于表的列数,取数据表的所有列
if (Columns.Count > Table.Columns.Count)
{
for (int s = Table.Columns.Count + ; s <= Columns.Count; s++)
{
Columns.RemoveAt(s); //移除数据表列数后的所有列
}
} //遍历所有的数据列,如果有数据列的数据类型不是 DataColumn,则将它移除
DataColumn column = new DataColumn();
for (int j = ; j < Columns.Count; j++)
{
try
{
column = (DataColumn)Columns[j];
}
catch (Exception)
{
Columns.RemoveAt(j);
}
}
if ((Table.TableName.Trim().Length == ) || (Table.TableName.ToLower() == "table"))
{
Table.TableName = "Sheet1";
} //数据表的列数
int ColCount = Columns.Count; //创建参数
OleDbParameter[] para = new OleDbParameter[ColCount]; //创建表结构的SQL语句
string TableStructStr = @"Create Table " + Table.TableName + "("; //连接字符串
string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 8.0;";
OleDbConnection objConn = new OleDbConnection(connString); //创建表结构
OleDbCommand objCmd = new OleDbCommand(); //数据类型集合
ArrayList DataTypeList = new ArrayList();
DataTypeList.Add("System.Decimal");
DataTypeList.Add("System.Double");
DataTypeList.Add("System.Int16");
DataTypeList.Add("System.Int32");
DataTypeList.Add("System.Int64");
DataTypeList.Add("System.Single"); DataColumn col = new DataColumn(); //遍历数据表的所有列,用于创建表结构
for (int k = ; k < ColCount; k++)
{
col = (DataColumn)Columns[k]; //列的数据类型是数字型
if (DataTypeList.IndexOf(col.DataType.ToString().Trim()) >= )
{
para[k] = new OleDbParameter("@" + col.Caption.Trim(), OleDbType.Double);
objCmd.Parameters.Add(para[k]); //如果是最后一列
if (k + == ColCount)
{
TableStructStr += col.Caption.Trim() + " Double)";
}
else
{
TableStructStr += col.Caption.Trim() + " Double,";
}
}
else
{
para[k] = new OleDbParameter("@" + col.Caption.Trim(), OleDbType.VarChar);
objCmd.Parameters.Add(para[k]); //如果是最后一列
if (k + == ColCount)
{
TableStructStr += col.Caption.Trim() + " VarChar)";
}
else
{
TableStructStr += col.Caption.Trim() + " VarChar,";
}
}
} //创建Excel文件及文件结构
try
{
objCmd.Connection = objConn;
objCmd.CommandText = TableStructStr; if (objConn.State == ConnectionState.Closed)
{
objConn.Open();
}
objCmd.ExecuteNonQuery();
}
catch (Exception exp)
{
throw exp;
} //插入记录的SQL语句
string InsertSql_1 = "Insert into " + Table.TableName + " (";
string InsertSql_2 = " Values (";
string InsertSql = ""; //遍历所有列,用于插入记录,在此创建插入记录的SQL语句
for (int colID = ; colID < ColCount; colID++)
{
if (colID + == ColCount) //最后一列
{
InsertSql_1 += Columns[colID].ToString().Trim() + ")";
InsertSql_2 += "@" + Columns[colID].ToString().Trim() + ")";
}
else
{
InsertSql_1 += Columns[colID].ToString().Trim() + ",";
InsertSql_2 += "@" + Columns[colID].ToString().Trim() + ",";
}
} InsertSql = InsertSql_1 + InsertSql_2; //遍历数据表的所有数据行
DataColumn DataCol = new DataColumn();
for (int rowID = ; rowID < Table.Rows.Count; rowID++)
{
for (int colID = ; colID < ColCount; colID++)
{
//因为列不连续,所以在取得单元格时不能用行列编号,列需得用列的名称
DataCol = (DataColumn)Columns[colID];
if (para[colID].DbType == DbType.Double && Table.Rows[rowID][DataCol.Caption].ToString().Trim() == "")
{
para[colID].Value = ;
}
else
{
para[colID].Value = Table.Rows[rowID][DataCol.Caption].ToString().Trim();
}
}
try
{
objCmd.CommandText = InsertSql;
objCmd.ExecuteNonQuery();
}
catch (Exception exp)
{
string str = exp.Message;
}
}
try
{
if (objConn.State == ConnectionState.Open)
{
objConn.Close();
}
}
catch (Exception exp)
{
throw exp;
}
return true;
}
#endregion /// <summary>
/// 获取Excel文件数据表列表
/// </summary>
public static ArrayList GetExcelTables(string ExcelFileName)
{
System.Data.DataTable dt = new System.Data.DataTable();
ArrayList TablesList = new ArrayList();
if (File.Exists(ExcelFileName))
{
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + ExcelFileName))
{
try
{
conn.Open();
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
}
catch (Exception exp)
{
throw exp;
} //获取数据表个数
int tablecount = dt.Rows.Count;
for (int i = ; i < tablecount; i++)
{
string tablename = dt.Rows[i][].ToString().Trim().TrimEnd('$');
if (TablesList.IndexOf(tablename) < )
{
TablesList.Add(tablename);
}
}
}
}
return TablesList;
} /// <summary>
/// 将Excel文件导出至DataTable(第一行作为表头)
/// </summary>
/// <param name="ExcelFilePath">Excel文件路径</param>
/// <param name="TableName">数据表名,如果数据表名错误,默认为第一个数据表名</param>
public static DataTable InputFromExcel(string ExcelFilePath, string TableName)
{
if (!File.Exists(ExcelFilePath))
{
throw new Exception("Excel文件不存在!");
} //如果数据表名不存在,则数据表名为Excel文件的第一个数据表
ArrayList TableList = new ArrayList();
TableList = GetExcelTables(ExcelFilePath); if (TableName.IndexOf(TableName) < )
{
TableName = TableList[].ToString().Trim();
} DataTable table = new DataTable();
OleDbConnection dbcon = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 8.0");
OleDbCommand cmd = new OleDbCommand("select * from [" + TableName + "$]", dbcon);
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd); try
{
if (dbcon.State == ConnectionState.Closed)
{
dbcon.Open();
}
adapter.Fill(table);
}
catch (Exception exp)
{
throw exp;
}
finally
{
if (dbcon.State == ConnectionState.Open)
{
dbcon.Close();
}
}
return table;
} /// <summary>
/// 获取Excel文件指定数据表的数据列表
/// </summary>
/// <param name="ExcelFileName">Excel文件名</param>
/// <param name="TableName">数据表名</param>
public static ArrayList GetExcelTableColumns(string ExcelFileName, string TableName)
{
DataTable dt = new DataTable();
ArrayList ColsList = new ArrayList();
if (File.Exists(ExcelFileName))
{
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + ExcelFileName))
{
conn.Open();
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, TableName, null }); //获取列个数
int colcount = dt.Rows.Count;
for (int i = ; i < colcount; i++)
{
string colname = dt.Rows[i]["Column_Name"].ToString().Trim();
ColsList.Add(colname);
}
}
}
return ColsList;
}
}
}
OleDbExcelHelper
网上搜集的常用类,这里不再测试。
方案四
将Excel另存为xml文件,对xml文件进行操作。
<Row>
<Cell><Data ss:Type="String">998</Data></Cell>
<Cell><Data ss:Type="String">柳雪巧</Data></Cell>
<Cell><Data ss:Type="String">f</Data></Cell>
<Cell><Data ss:Type="String">1971/4/30 0:00:00</Data></Cell>
<Cell><Data ss:Type="String">2005/1/15 0:00:00</Data></Cell>
<Cell><Data ss:Type="String">*省 屏东县</Data></Cell>
<Cell><Data ss:Type="String">Dolores19710430@139.com</Data></Cell>
<Cell><Data ss:Type="String">12616310511</Data></Cell>
<Cell><Data ss:Type="String">False</Data></Cell>
<Cell><Data ss:Type="String">2014/3/15 10:13:54</Data></Cell>
<Cell><Data ss:Type="String">5</Data></Cell>
</Row>
excel表格中每一行数据,其实是以上格式的xml,有规律,就可以很容易的去解析。
方案五
js插件
官网地址:http://datatables.net/extras/tabletools/
方案六
导出为csv文件
分享一个辅助类
using System.Data;
using System.IO; public static class CsvHelper
{
/// <summary>
/// 导出报表为Csv
/// </summary>
/// <param name="dt">DataTable</param>
/// <param name="strFilePath">物理路径</param>
/// <param name="tableheader">表头</param>
/// <param name="columname">字段标题,逗号分隔</param>
public static bool dt2csv(DataTable dt, string strFilePath, string tableheader, string columname)
{
try
{
string strBufferLine = "";
StreamWriter strmWriterObj = new StreamWriter(strFilePath,false,System.Text.Encoding.UTF8);
strmWriterObj.WriteLine(tableheader);
strmWriterObj.WriteLine(columname);
for (int i = ; i < dt.Rows.Count; i++)
{
strBufferLine = "";
for (int j = ; j < dt.Columns.Count; j++)
{
if (j > )
strBufferLine += ",";
strBufferLine += dt.Rows[i][j].ToString();
}
strmWriterObj.WriteLine(strBufferLine);
}
strmWriterObj.Close();
return true;
}
catch
{
return false;
}
} /// <summary>
/// 将Csv读入DataTable
/// </summary>
/// <param name="filePath">csv文件路径</param>
/// <param name="n">表示第n行是字段title,第n+1行是记录开始</param>
public static DataTable csv2dt(string filePath, int n, DataTable dt)
{
StreamReader reader = new StreamReader(filePath, System.Text.Encoding.UTF8, false);
int i = , m = ;
reader.Peek();
while (reader.Peek() > )
{
m = m + ;
string str = reader.ReadLine();
if (m >= n + )
{
string[] split = str.Split(','); System.Data.DataRow dr = dt.NewRow();
for (i = ; i < split.Length; i++)
{
dr[i] = split[i];
}
dt.Rows.Add(dr);
}
}
return dt;
}
}
不再测试。
方案七
使用模版的方式,最简单的模版,就是将表头列出,然后再导入数据。第一行为表头,从第二行开始写入数据。导入过程可参考前面的解决方案。
方案八
使用Aspose.Cells组件,貌似收费。
可参考:http://www.cnblogs.com/lanyue52011/p/3372452.html
http://www.cnblogs.com/hongjiumu/archive/2013/03/15/2962277.html
http://www.cnblogs.com/wujy/archive/2012/07/19/2600162.html
方案九
OpenXML
OpenXML库:DocumentFormat.OpenXml.dll;
参考:http://www.cnblogs.com/zlgcool/archive/2008/12/31/1365993.html
http://blog.sina.com.cn/s/blog_46e9573c01011bvs.html
方案十
Epplus操作Excel2007、2010
参考:http://www.cnblogs.com/xinchen/archive/2012/02/15/2352920.html
http://blog.csdn.net/rrrrssss00/article/details/6590944
总结
列出常见的几种解决方案,在实际项目中,用哪一种,还是根据项目环境来决定吧。
最近项目中用到了Excel导出,导入的功能,就想着将常见的方式总结一下。也许还有遗漏,请留言,将你知道也分享给大家,谢谢。
如果该文章对你有所帮助,不妨推荐一下,让更多的人知道,毕竟分享是件快乐的事情。
代码下载:链接:http://pan.baidu.com/s/1dD3lleT 密码:axli