ASP.NET操作EXCEL的总结篇(4)


//合并标段列
index = 0; rowid = 3; //重置变量
string pa_name = string.Empty; //标段名称
for (k = 3; k <= i + 2; k++)
{
pa_name = table.Rows[index]["PA_NAME"].ToString();
if (wksheet.get_Range(wksheet.Cells[k, 4], wksheet.Cells[k, 4]).Value2.ToString() == pa_name)
{
wksheet.get_Range(wksheet.Cells[k, 4], wksheet.Cells[k, 4]).Value2 = "";
continue;
}
wksheet.get_Range(wksheet.Cells[rowid, 4], wksheet.Cells[k - 1, 4]).Merge(Missing.Value);
wksheet.get_Range(wksheet.Cells[rowid, 4], wksheet.Cells[rowid, 4]).Value2 = "'" + pa_name;
index = k - 3;
rowid = k;
k--;
}
//退出循环时合并最后一个项目的标段
wksheet.get_Range(wksheet.Cells[rowid, 4], wksheet.Cells[k - 1, 4]).Merge(Missing.Value);
wksheet.get_Range(wksheet.Cells[rowid, 4], wksheet.Cells[rowid, 4]).Value2 = "'" + pa_name;
tick = DateTime.Now.ToString("yyyyMMddhhmmss");
save_path = temp_path + "\\" + tick + "保证金收退情况表.xls";
Session["BailBackID"] = tick + "保证金收退情况表.xls";
Session["_BailBack"] = "true";
workbook.SaveAs(save_path, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
excelOperate.Dispose(worksheet, workbook, app);//关闭Excel进程
//DownLoad(save_path);
//Page_Close();


当然,上面的操作中会进行好几次循环,在性能方面不太可取,园子里的兄弟也许会有更好的方法,小弟不吝赐教了
下面我们看下几个效果图:

ASP.NET操作EXCEL的总结篇



ASP.NET操作EXCEL的总结篇



ASP.NET操作EXCEL的总结篇


(注意:这里提示的导出数据是指从数据库成功取出数据,还没有操作EXCEL对象,刚开始已经说过了,当然这个提示文字换成其它的也可以)

ASP.NET操作EXCEL的总结篇



ASP.NET操作EXCEL的总结篇



整个过程采用AJAX提示的,一来不刷新,二来导出时间比较长的话,可以给客户一个良好的体验效果,否可,用户一点导出按钮,半天没反应也没提示,客户就觉得怎么这么慢的,是不是你们程序有问题,指责一大堆,有了这么些交互提示信息,让客户多等几分钟也能承受。

     3.生成的表格包含多个sheet的操作,比如下面一种情况

ASP.NET操作EXCEL的总结篇



绘制这张表的要求是根据选择某年的几月到几月,生成这个几个月的一个综合情况的sheet,然后分别生成这几个月的单独的sheet表,生成上面表的模板,包含两个sheet ,一个综合月份的sheet和一个单独月份的sheet,因为单独月份的sheet表现形式都是一样的,我们可以根据选择的月份个数Copy几个sheet就可以了

复制代码 代码如下:


Workbooks workbooks = app.Workbooks;
_Workbook workbook = workbooks.Add(template_path + "\\招标单位年度招标情况逐月统计表.xls");
Sheets sheets = workbook.Worksheets;
_Worksheet Yearsheet = (_Worksheet)sheets.get_Item(1);
_Worksheet worksheet = (_Worksheet)sheets.get_Item(2);
if (worksheet == null)
{
return;
}
for (int i = 1; i < monthCount; i++)
worksheet.Copy(Missing.Value, workbook.Worksheets[2]);//月统计工作薄


Yearsheet的操作就不说了,和前面几个一样操作,关键是月份的sheet的生成,其实就是循环操作get_Item(i),代码如下

复制代码 代码如下:


//////////////////////////////////////每月详细统计////////////////////////////////////
int item_id = 2;
rowNum = 0; book_Amount = 0; index = 0;
bid_Amount = ""; bidser_Amount = ""; agent_Amount = 0;//清空变量
_Worksheet ws = null;
for (int i = 0; i < tableMM.Rows.Count; i++)
{
rowNum++;
Month = tableMM.Rows[index]["DATE_MONTH"].ToString();
if (tableMM.Rows[i]["DATE_MONTH"].ToString() == Month)
{
ws = (_Worksheet)sheets.get_Item(item_id);
ws.Cells[3 + rowNum - 1, 1] = rowNum;
ws.Cells[3 + rowNum - 1, 2] = tableMM.Rows[i]["PROJNO"];
ws.Cells[3 + rowNum - 1, 3] = tableMM.Rows[i]["PROJNAME"];
ws.Cells[3 + rowNum - 1, 4] = tableMM.Rows[i]["BID_TYPE"];
ws.Cells[3 + rowNum - 1, 5] = tableMM.Rows[i]["BID_MODE"];
ws.Cells[3 + rowNum - 1, 6] = tableMM.Rows[i]["OPENDT"];
ws.Cells[3 + rowNum - 1, 7] = tableMM.Rows[i]["OPENADDRESS"];
ws.Cells[3 + rowNum - 1, 8] = tableMM.Rows[i]["BID_UNIT"];
ws.Cells[3 + rowNum - 1, 9] = tableMM.Rows[i]["NOTICE_NO"].ToString().Replace("神华国贸", "");
ws.Cells[3 + rowNum - 1, 10] = tableMM.Rows[i]["BOOKAMOUNT"];
ws.Cells[3 + rowNum - 1, 11] = tableMM.Rows[i]["BIDPRICE"] + "(万" + tableMM.Rows[i]["CURRENCY"] + ")";
ws.Cells[3 + rowNum - 1, 12] = tableMM.Rows[i]["BIDSER_AMOUNT"] + "(万" + tableMM.Rows[i]["CURRENCY"]+")";
ws.Cells[3 + rowNum - 1, 13] = tableMM.Rows[i]["AGT_AMOUNT"];
ws.Cells[3 + rowNum - 1, 14] = "";
ws.get_Range(ws.Cells[3 + rowNum - 1, 1], ws.Cells[3 + rowNum - 1, 14]).Borders.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
continue;
}
ws.Cells[1, 1] = year + "年" + bidName + GetMonth(Month) + "月份招标项目情况一览表";
//每月合计
sql = " SELECT CURRENCY, NVL(SUM(BIDPRICE),0) AS BIDPRICE,NVL(SUM(BOOKAMOUNT),0) AS BOOKAMOUNT,NVL(SUM(BIDSER_AMOUNT),0) AS BIDSER_AMOUNT,NVL(SUM(AGT_AMOUNT),0) AS AGT_AMOUNT FROM IBS_V_BID_MONTHLY_STAT" + SqlFilter +
" AND DATE_YEAR ='" + year + "' AND COMPANY_ID=" + biderID + " AND DATE_MONTH ='" + Month + "'" +
" GROUP BY CURRENCY";
System.Data.DataTable dt1 = OracleHelper.RetDataTable(sql);
for (int m = 0; m < dt1.Rows.Count; m++)
{
bid_Amount += dt1.Rows[m]["BIDPRICE"] + "(万"+dt1.Rows[m]["CURRENCY"] + ")\r\t";
book_Amount += float.Parse(dt1.Rows[m]["BOOKAMOUNT"].ToString());
bidser_Amount += dt1.Rows[m]["BIDSER_AMOUNT"] + "(万" + dt1.Rows[m]["CURRENCY"] + ")\r\t";
agent_Amount += float.Parse(dt1.Rows[m]["AGT_AMOUNT"].ToString());
}
ws.Cells[3 + rowNum - 1, 3] = "合 计";
ws.Cells[3 + rowNum - 1, 10] = book_Amount;
ws.Cells[3 + rowNum - 1, 11] = bid_Amount;
ws.Cells[3 + rowNum - 1, 12] = bidser_Amount;
ws.Cells[3 + rowNum - 1, 13] = agent_Amount;
ws.get_Range(ws.Cells[3 + rowNum - 1, 1], ws.Cells[3 + rowNum - 1, 14]).Borders.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
ws.Name = GetMM(Month);
item_id++;
index = i; //汇总下一个月份的招标项目
i--;
rowNum = 0; book_Amount = 0;
bid_Amount = ""; bidser_Amount = ""; agent_Amount = 0;//清空变量
}
//跳出循环时进行最后一个月份的项目汇总


用的是oracle数据库,所以上面那个sql语句。。。 呵呵
============================================================================================
上面大致说得就差不多了,因为是不断循环的什么的,可能对于大的数据量读写来说,比较好性能,如果大家有什么更好的方法,可以指点下,为了弥补等待时间过长,所以才结合了AJAX来处理。
最后我把做的一个小demo的链接帖出来给大家,还有一些空模板和对应生成的数据表给大家对照看下,尤其相对复杂一些的表画应该是能画出来的,主要看大家采用什么样的方法,能少循环一次就尽量少循环,呵呵~~~
EXCEL模板读写说明



(说明:最后弹出下载文件的一个页面一直想让其自动关掉,但是不行,如果不关掉,再点导出,不会弹出下载框,实际的处理中我们可以在导出旁边放个下载按钮,就像上面的效果图里那样,当然可以点导出的时候让其在网页中直接打开,点下载的时候再弹出下载框,但是直接打开的话,文件需要生成在虚拟目录下,不太安全,呵呵~~,看实际情况处理了)
==========================================================================================
今天补充说明下,关于那个调用ajax回调的效果,有个地方用到了所谓的“ajax嵌套调用”,如下

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjjdzf.html