我写的一个ExcelHelper通用类,可用于读取或生成数据

读取或生成EXCEL数据的方法有很多,一般常见的有:

1.通过OFFICE EXCEL组件,优点:读取与生成EXCEL文件方便,缺点:服务器上必须安装OFFICE软件,且进程无法及时释放

2.通过第三方组件(比如:NPOI),优点:无需安装OFFICE软件,缺点:需要引入第三方组件,当然这个还是比较强的

3.通过把EXCEL当成数据库,连接后运用SQL语句读取,写入的话就自行拼接成HTML表格,优点:无需另外的组件,缺点:需要会SQL及拼接HTML表格较麻烦;

三种方法我都有用过,若开发BS网站程序,建议采用第二种、第三种方法,若开发CS结构,建议采用第一种或第二种;

以下是我针对BS端写的一个ExcelHelper通用类,可用于读取或生成数据,比较方便,技术原理是上述的第三种方法,代码如下,可能存在缺陷,高手见谅:

namespace ASOTS.Models
{
    public abstract class ExcelHelper
    {
        /// <summary>
        /// 获取EXCEL中指定sheet内容
        /// </summary>
        /// <returns></returns>
        public static DataTable GetTableFromExcel(string filePath, string fileExt, string tableName, int colsCount)
        {
            string connstr = null;
            if (fileExt == ".xls")
            {
                connstr = "Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source =" + filePath + ";Extended Properties=‘Excel 8.0;HDR=Yes;IMEX=1‘";
            }
            else
            {
                connstr = "Provider = Microsoft.ACE.OLEDB.12.0 ; Data Source =" + filePath + ";Extended Properties=‘Excel 12.0;HDR=Yes;IMEX=1‘";
            }

            using (OleDbConnection excelConn = new OleDbConnection(connstr))
            {
                excelConn.Open();

                //获取EXCEL架构信息
                DataTable schemaTable = excelConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });

                //判断指定sheet名是否存在
                DataView schemaView = new DataView(schemaTable);
                schemaView.RowFilter = "TABLE_NAME=‘" + tableName + "$‘";
                schemaTable = schemaView.ToTable();

                if (schemaTable != null && schemaTable.Rows.Count > 0)
                {
                    DataTable schemaTable_Cols = excelConn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, tableName + "$", null });
                    schemaView = new DataView(schemaTable_Cols);
                    schemaView.RowFilter = "ORDINAL_POSITION<=" + colsCount.ToString();
                    schemaView.Sort = "ORDINAL_POSITION asc";
                    schemaTable_Cols = schemaView.ToTable();
                    string selectCols = "";
                    for (int i = 0; i < schemaTable_Cols.Rows.Count; i++)
                    {
                        selectCols += "," + schemaTable_Cols.Rows[i]["COLUMN_NAME"].ToString();
                    }

                    selectCols = selectCols.Substring(1);

                    //查询sheet中的数据
                    string strSql = "select " + selectCols + " from [" + tableName + "$]";
                    OleDbDataAdapter da = new OleDbDataAdapter(strSql, excelConn);
                    DataSet ds = new DataSet();
                    da.Fill(ds, tableName);
                    excelConn.Close();
                    return ds.Tables[tableName];
                }
                else
                {
                    excelConn.Close();
                    return null;
                }
            }

        }

        /// <summary>
        /// 将数据模型集合对象生成HTML表格字符串
        /// </summary>
        /// <param name="data"></param>
        /// <param name="tableAttributes"></param>
        /// <param name="headers"></param>
        /// <returns></returns>
        public static string SetDataToHtmlTable(IEnumerable data, string tableAttributes, params KeyValuePair<string, string>[] headers)
        {
            StringBuilder htmlTableBuilder = new StringBuilder();
            htmlTableBuilder.AppendFormat("<table {0}>", tableAttributes);

            if (data.GetEnumerator().Current == null)
            {
                throw new Exception("没有获取到任何数据!");
            }

            Type t = data.GetEnumerator().Current.GetType();

            string[] cellIndexs = new string[headers.Count()];

            htmlTableBuilder.Append("<tr>");
            for (int i = 0; i < headers.Count(); i++)
            {
                cellIndexs[i] = headers[i].Key;
                htmlTableBuilder.AppendFormat("<th>{0}</th>", headers[i].Value);
            }
            htmlTableBuilder.Append("</tr>");

            foreach (var item in data)
            {
                htmlTableBuilder.Append("<tr>");
                for (int i = 0; i < cellIndexs.Length; i++)
                {
                    object pValue = t.GetProperty(cellIndexs[i]).GetValue(item, null);
                    htmlTableBuilder.AppendFormat("<td>{0}</td>", pValue);
                }
                htmlTableBuilder.Append("</tr>");
            }

            htmlTableBuilder.Append("</table>");

            return htmlTableBuilder.ToString();
        }

        /// <summary>
        /// 将DataTable对象生成HTML表格字符串
        /// </summary>
        /// <param name="data"></param>
        /// <param name="tableAttributes"></param>
        /// <param name="headers"></param>
        /// <returns></returns>
        public static string SetDataToHtmlTable(DataTable dataTable, string tableAttributes, params KeyValuePair<string, string>[] headers)
        {
            StringBuilder htmlTableBuilder = new StringBuilder();
            htmlTableBuilder.AppendFormat("<table {0}>", tableAttributes);

            htmlTableBuilder.Append("<tr>");
            for (int i = 0; i < headers.Count(); i++)
            {
                htmlTableBuilder.AppendFormat("<th>{0}</th>", headers[i].Value);
            }
            htmlTableBuilder.Append("</tr>");

            foreach (DataRow row in dataTable.Rows)
            {
                htmlTableBuilder.Append("<tr>");
                for (int i = 0; i < headers.Count(); i++)
                {
                    htmlTableBuilder.AppendFormat("<td>{0}</td>", row[headers[i].Key]);
                }
                htmlTableBuilder.Append("</tr>");
            }

            htmlTableBuilder.Append("</table>");

            return htmlTableBuilder.ToString();
        }

    }

    public class KeyValueList<TKey, TValue> : List<KeyValuePair<TKey, TValue>>
    {
        public void Add(TKey key, TValue value)
        {
            base.Add(new KeyValuePair<TKey, TValue>(key, value));
        }
    }
}

调用方法如下:

//读数据
DataTable resultTable = ExcelHelper.GetTableFromExcel(saveFilePath, fileExt, "data", 10);

//生成表格(以下是MVC调用,WEBFORM同理)
KeyValueList<string, string> headers = new KeyValueList<string, string>() {
                        {"year","年 份"},
                        {"month","月 份"},
                        {"stage1count","一 阶"},
                        {"stage2count","二 阶"},
                        {"stage3count","三 阶"},
                        {"stage4count","四 阶"},
                        {"yearincount","一年内进厂"},
                        {"stagetotalcount","基盘客户总数"},
                        {"stage1rate","一阶占比"},
                        {"stage2rate","二阶占比"},
                        {"stage3rate","三阶占比"},
                        {"stage4rate","四阶占比"}
                };

                string tableAttributes = "border=‘1‘ cellspacing=‘3‘ cellpadding=‘3‘";

                string htmlTable=ExcelHelper.SetDataToHtmlTable(model, tableAttributes, headers.ToArray());
                byte[] b = System.Text.Encoding.UTF8.GetBytes(htmlTable);

                return File(b, "application/vnd.ms-excel", string.Format("StageSummary_{0}_{1}_{2}.xls",orgcode,startym,endym));

其中:KeyValueList是我创建的一个集合类,主要用于生成表头,以及表头与数据列对应,之所以写成类,是因为若直接使用:List<KeyValuePair<TKey, TValue>>,则无法直接使用集合初始化器,就必需得一个一个的添加对象,有些繁琐,增加了ADD方法后,就可以直接用:new KeyValueList<string, string>() {{"",""},...}很方便,有人可能说为什么不用SortedDictionary等现有排序类,原因是SortedDictionary是基于Key排序,而此处是采用ADD的先后顺序来固定顺序的。

更多IT相关资讯与技术文章,欢迎光临我的个人网站:http://www.zuowenjun.cn/

时间: 2024-10-11 17:09:53

我写的一个ExcelHelper通用类,可用于读取或生成数据的相关文章

一个完整的类用来读取OpenSSL生成的pem格式的x509证书

1 internal static class CcbRsaHelper 2 { 3 private const string Begin = "-----BEGIN "; 4 private const string End = "-----END "; 5 private const string Private = "PRIVATE KEY"; 6 7 /// <summary>Imports PEM formatted key

C#.NET 程序员的福利,自己写的一个XML操作类,可实现像jquery一样方便的xml操作,且不用专门去处理命名空间。

此工具是进入一家新公司之后实现的,主要是工作当中操作 xml 的时间太多,因为公司按任务计“工作量”,领导给我安排的时间远远不够完善此工具[悲哀的制度],虽然我也能直接在cs中直接中规中矩完成,但实在受不了那种重复和低效,所以此工具基础部分绝大部分时间是在家中加班完成,剩下应用于公司项目中之后,在公司改了一些BUG,差不多也用了半年多了,实在是很好用,现在也差不多稳定了,特分享出来,需要的直接拿去用吧,有BUG可以直接发消息给我沟通,不用谢.. 使用方法: x(filepath).Find("/

刚写的一个js分页类,未优化

以前也写过,很久以前了,写的很长,并且使用起来也不灵活.这次搞了个灵活版的. /* * SunPage --自定义分页类,仅获取分页的html代码,简单应用 * Sunbt 2015-5-4 * v1.0 * @param current_page int 当前页 * @param totle_page int 总页数 * @param take_num int 当前页左右携带页码数 * @param func_obj obj 分页实现函数 */ var SunPage = function(c

怎么写好一个C++的类(二)不建议直接include包含cpp文件

在很多书上都教了#include包含头文件,但是没有教为什么不能包含源文件...所以有一些同学试过直接包含源文件(好吧,我承认,我在大学时候也这样做过,而且很幸运没有出问题). 那到底应不应该包含源文件呢? 我想用一个反证法,如果直接包含.cpp文件,那cpp文件中的static变量和接口不是全暴露给外部的.cpp文件了吗,那样要static和接口的在本文件生命周期有效这一个限定有毛用?不直接包含源文件,就可以把程序按照文件进行模块划分.(可能很多同学说,总是说模块化,就知道吹这些名词,都不感觉

新手写的一个DBCP工具类

1 package com.xx.questionnaire.util.dao; 2 3 import java.io.IOException; 4 import java.sql.Connection; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.sql.Statement; 9 import java.util.P

高吞吐量的一个日志函数类_用于IOCP (Delphi)

在开发服务器端程序的时候,日志是必须的一个功能.由于服务器端的要频繁的把数据写入日志,开始的时候用了一个很简单日志函数 就是直接把日志字符写入文件中.然后关闭连接.一直也应用良好.但做压力测试的时候,因为要每个连接的数据都要写入日志,发现运行的一段时间后,频繁掉线,CPU占用率,居高不下,优化了可以想到的很多地方,有一定的效果,仔细观察发现,硬盘灯狂闪不止,说明硬盘I/0操作过于紧张.但测试的时候,基本是不读写硬盘的,恍然发现,是日志函数影响到整个系统的性能.每一个日志数据的时候,就要打开文件,

原生JS写了一个小demo,根据输入的数字生成不同背景颜色的小方块儿~

昨天练习写了这个小demo,个人觉得通过设置定位元素left和top的值,来实现换行的功能,这种方法很巧妙~ 另外,如下代码中的随机颜色的获取,还请各位前辈多多指教:需要改进的地方:或者有没有更好的方法. 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style type="text

PHP自定义弹出消息类,用于弹出提示信息并返回

一个用PHP自写的弹出消息类,用于在程序出错时弹出提示,,弹出警告框,或在程序运行到某阶段的快捷提示,需用时只需传入参数即可,函数并不复杂,但觉得挺实用.具体代码: function Alert($alert,$goback=0){ if($I_goback<>0){ echo "<script>alert('$alert');history.go($goback);</script>"; }else{ echo "<script&g

分享最近抽空写的一个代码生成器,集成EasyDBUtility数据库访问帮助类

一直想写一个自己的代码生成器,但是因为工作事情多,一直搁置下来,最近下决心终于利用下班时间写完了,现在分享给有需要的朋友,代码生成器集成EasyDBUtility数据库访问帮助类,暂时只支持sqlserver数据库,界面如下 部分代码如下 using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Te