收到消息,下星期又有导出 Excel 报表的代码要写。
心想,不就是 OleDb 先 CREATE 表, 然后 INSERT 么?
都是体力活啊......

结果拿到纸张的报表,我就悲剧了。
报表的结构,像下面这种结构,行/列都不确定的

因为
行是日期,外部用户指定
列是物品,可能有,可能没有,取决于外部用户的日期范围。

如果在C#里面,先把所有出现过的物品,作为列名
然后再自己分别组合计算,最后再去 OleDb 那里去 CREATE + INSERT 嘛
这个报表又有个那么大的标题。

假如显示的报表,是一个 Sheet ,报表的数据在另外一个 Sheet 里面。
我C#导出 Excel 的时候,把数据写到一个 [数据Sheet] 里面。
显示的 [报表Sheet] 里面,设置好引用那个 [数据Sheet] 的数据。
想一下,应该是可行的。

既然应该是可行的,那么我C#里面,干脆连计算也别计算了。
因为这样的效果,在 Excel 里面,使用数据透视表,点个三五下,就结束的工作。
我还跑C#里面计算来计算去的,还容易出错。

首先嘛,先去创建一个模版 Excel, 2个 Sheet
1个[数据Sheet],1个[报表Sheet]
然后[数据Sheet]里面,造点测试数据,
[报表Sheet] 里面,折腾好格式 与 数据透视表

这个模版就暂时保存为 Template.xls

然后这个文件,加入 C# 的项目,设置为 “如果较新则复制”

C# 项目,是一个 WinForm 的项目,就2按钮
1个是把数据 通过 OleDB 写进 Excel
1个是更新 Excel 中的 数据透视表信息。

按钮1的代码

        /// <summary>
/// 使用模版文件创建 Excel 文件.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnUseTemplate_Click(object sender, EventArgs e)
{
// 如果文件存在,先删除.
if (File.Exists(EXCEL_FILE_NAME))
{
File.Delete(EXCEL_FILE_NAME);
}
// 模版复制为目标文件.
string filePath = HttpContext.Current.Request.MapPath("temp/Template.xls");
File.Copy(filePath, EXCEL_FILE_NAME);
String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + EXCEL_FILE_NAME + ";Extended Properties=Excel 8.0;";
//excel2007的ConnectionString,其中Microsoft.Jet.OLEDB.12.0必须安装AccessDatabaseEngine.exe
//String sConnectionString = "Provider=Microsoft.Jet.OLEDB.12.0;" + "Data Source=" + EXCEL_FILE_NAME + ";Extended Properties=Excel 12.0;";
OleDbConnection cn = new OleDbConnection(sConnectionString);
// 打开连接.
cn.Open();
string sqlCreate =
@"CREATE TABLE [销售数据] ([日期] Date, [商品] VarChar, [数量] Int)";
OleDbCommand cmd = new OleDbCommand(sqlCreate, cn);
// 创建 Sheet
cmd.ExecuteNonQuery();
OleDbCommand icmd = new OleDbCommand();
icmd.Connection = cn;
icmd.CommandText = "INSERT INTO [销售数据] ([日期], [商品], [数量]) VALUES (@SaleData, @SaleGoods, @SaleMoney)";
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
OleDbParameter[] paraArray = new OleDbParameter[];
paraArray[] = new OleDbParameter("@SaleData", OleDbType.Date);
paraArray[] = new OleDbParameter("@SaleGoods", OleDbType.VarChar);
paraArray[] = new OleDbParameter("@SaleMoney", OleDbType.Integer);
paraArray[].Value = DateTime.Today.AddDays(-i);
paraArray[].Value = "商品" + j;
paraArray[].Value = i + j;
icmd.Parameters.Clear();
icmd.Parameters.AddRange(paraArray);
icmd.ExecuteNonQuery();
}
}
cn.Close();
MessageBox.Show("处理完毕!!!");
}

按钮2的代码

        /// <summary>
/// 更新数据透视表的数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnBuildData_Click(object sender, EventArgs e)
{
ExcelService service = new ExcelService();
// 打开 Excel.
service.OpenExcel();
// 打开 Excel 文件.
//service.OpenExcelFile(AppDomain.CurrentDomain.BaseDirectory + EXCEL_FILE_NAME);
service.OpenExcelFile(EXCEL_FILE_NAME);
// 设置 数据透视表数据.
service.AddPivotTable("销售数据", "统计报表", "数据透视表1");
// 保存 Excel 文件.
service.SaveExcelFile();
// 关闭 Excel.
service.CloseExcel();
MessageBox.Show("处理完毕!!!");
}

其中 ExcelService  的代码如下 :

using System;
using System.Data;
using System.Drawing;
using Excel = Microsoft.Office.Interop.Excel;
namespace ZXCCLib.Web.UILoader.Test
{
/// <summary>
/// Excel 服务.
/// </summary>
public class ExcelService
{
#region OPEN WORKBOOK VARIABLES
private static object vk_missing = System.Reflection.Missing.Value;
private static object vk_visible = true;
private static object vk_false = false;
private static object vk_true = true;
private object vk_update_links = ;
private object vk_read_only = vk_true;
private object vk_format = ;
private object vk_password = vk_missing;
private object vk_write_res_password = vk_missing;
private object vk_ignore_read_only_recommend = vk_true;
private object vk_origin = vk_missing;
private object vk_delimiter = vk_missing;
private object vk_editable = vk_false;
private object vk_notify = vk_false;
private object vk_converter = vk_missing;
private object vk_add_to_mru = vk_false;
private object vk_local = vk_false;
private object vk_corrupt_load = vk_false;
#endregion
/// <summary>
/// Excel App.
/// </summary>
private Excel.Application xlApp;
/// <summary>
/// Excel 工作簿.
/// </summary>
private Excel.Workbook xlBook = null;
/// <summary>
/// Excel 工作表.
/// </summary>
private Excel.Worksheet xlSheet = null;
/// <summary>
/// 打开 Excel.
/// </summary>
public void OpenExcel()
{
// 启动 Excel.
xlApp = new Excel.ApplicationClass();
// 可见/不可见.
xlApp.Visible = true;
xlApp.UserControl = true;
xlApp.DisplayAlerts = true;
} /// <summary>
/// 退出 Excel.
/// </summary>
public void CloseExcel()
{
xlApp.DisplayAlerts = false;
xlApp.Workbooks.Close();
xlApp.Quit();
}
/// <summary>
/// 打开 Excel 文件.
/// </summary>
/// <param name="excelFile"></param>
public void OpenExcelFile(String excelFile)
{
// 打开文件.
xlBook = xlApp.Workbooks.Open(excelFile,
vk_update_links, vk_missing, vk_format, vk_password,
vk_write_res_password, vk_ignore_read_only_recommend, vk_origin,
vk_delimiter, vk_editable, vk_notify, vk_converter, vk_add_to_mru,
vk_local, vk_corrupt_load);
// 取得第一个 Sheet.
foreach (Excel.Worksheet displayWorksheet in xlBook.Sheets)
{
xlSheet = displayWorksheet;
break;
}
}
/// <summary>
/// 保存 Excel 文件.
/// </summary>
public void SaveExcelFile()
{
xlBook.Save();
}
/// <summary>
/// 另存为 Excel 文件.
/// </summary>
public void SaveAsExcelFile(String asFileName)
{
xlBook.SaveCopyAs(asFileName);
} /// <summary>
/// 关闭 Excel 文件.
/// </summary>
public void CloseExcelFile()
{
xlBook.Close(false, false, false);
}
/// <summary>
/// 选择工作表.
/// </summary>
/// <param name="sheetName"></param>
public void SelectSheet(String sheetName)
{
// 选择工作表.
xlSheet = (Excel.Worksheet)xlBook.Sheets.get_Item(sheetName);
}
/// <summary>
/// 取得单元格文本.
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>
public String GetStringValue(int row, int col)
{
return xlSheet.get_Range(xlSheet.Cells[row, col], xlSheet.Cells[row, col]).Text.ToString().Trim();
}
/// <summary>
/// 设置单元格文本./// </summary>
/// <param name="row"></param>
/// <param name="col"></param>
/// <param name="value"></param>
public void SetValue(int row, int col, String value)
{
// 取得范围.
Excel.Range range = xlSheet.get_Range(xlSheet.Cells[row, col], xlSheet.Cells[row, col]);
// 原有的数值.
String oldValue = range.Text.ToString().Trim();
// 设置数值.
xlSheet.Cells[row, col] = value;
// 修改背景色
range.Interior.ColorIndex = ;
// 添加备注.
range.AddComment("修改前数值:" + oldValue);
}
/// <summary>
/// 设置指定单元格为 字符格式.
/// </summary>
/// <param name="row1"></param>
/// <param name="col1"></param>
/// <param name="row2"></param>
/// <param name="col2"></param>
public void SetTextFormat(int row1, int col1, int row2, int col2)
{
// 选择区域.
Excel.Range myrange = xlSheet.get_Range(xlSheet.Cells[row1, col1], xlSheet.Cells[row2, col2]);
// 文本格式
myrange.NumberFormatLocal = "@";
} /// <summary>
/// 更新数据透视表数据.
/// </summary>
/// <param name="dataSheerName">数据Sheet名</param>
/// <param name="pivotSheetName">报表Sheet名</param>
/// <param name="pivottableName">数据视图表名</param>
public void AddPivotTable(string dataSheerName, string pivotSheetName, string pivottableName)
{
// 首先定位到 数据的 Sheet. 设定 数据透视表的 的数据源.
xlSheet = null;
foreach (Excel.Worksheet displayWorksheet in xlBook.Sheets)
{
if (dataSheerName == displayWorksheet.Name)
{
xlSheet = displayWorksheet;
break;
}
}
if (xlSheet != null)
{
// 取得数据的Sheet的行数与列数
int rowCount = xlSheet.UsedRange.Rows.Count;
int colCount = xlSheet.UsedRange.Columns.Count;
// 拼写好 数据源的名字,准备后面用于更新 数据透视表的数据源.
string sourceData = dataSheerName + "!R1C1:R" + rowCount + "C" + colCount;
// 然后定位到 数据透视表的 Sheet. 刷新数据.
xlSheet = null;
foreach (Excel.Worksheet displayWorksheet in xlBook.Sheets)
{
if (pivotSheetName == displayWorksheet.Name)
{
xlSheet = displayWorksheet;
break;
}
}
if (xlSheet != null)
{
// 修改 Excel 文件中 数据透视表的 数据源
((Excel.PivotTable)xlSheet.PivotTables(pivottableName)).SourceData = sourceData;
// 刷新数据 : 重新计算 数据透视表数据
((Excel.PivotTable)xlSheet.PivotTables(pivottableName)).Update();
}
}
}
}
}

测试运行一下,按第一个按钮,先产生一个 [销售数据] 的Sheet.

按第2个按钮,
打开 Excel
设置 [统计报表]那个Sheet中,数据透视表的数据源为 [销售数据] 中的数据。
然后重新计算
最后保存

最后运行的结果如下:

---完---

【转】关于C#使用Excel的数据透视表的例子的更多相关文章

  1. ASP.NET实现类似Excel的数据透视表

    代码: /Files/zhuqil/Pivot.zip 数据透视表提供的数据三维视图效果,在Microsoft Excel能创建数据透视表,但是,它并不会总是很方便使用Excel.您可能希望在Web应 ...

  2. Excel学习 -- 数据透视表功能

    Excel -- 数据透视表基础 数据透视表(Pivot Table)是一种交互式的表,可以进行某些计算,如求和与计数等.所进行的计算与数据跟数据透视表中的排列有关.    之所以称为数据透视表,是因 ...

  3. VSTO学习笔记(十四)Excel数据透视表与PowerPivot

    原文:VSTO学习笔记(十四)Excel数据透视表与PowerPivot 近期公司内部在做一种通用查询报表,方便人力资源分析.统计数据.由于之前公司系统中有一个类似的查询使用Excel数据透视表完成的 ...

  4. 【技术分享:python 应用之一】如何使用 Python 对 Excel 做一份数据透视表

    客户这边,其中有一张如同上图所示的数据汇总表,然而需求是,需要将这张表数据做一个数据透视表,最后通过数据透视表中的数据,填写至系统数据库.拿到需求,首先就想到肯定不能直接用设计器去操作 Excel,通 ...

  5. 【转载】使用Pandas创建数据透视表

    使用Pandas创建数据透视表 本文转载自:蓝鲸的网站分析笔记 原文链接:使用Pandas创建数据透视表 目录 pandas.pivot_table() 创建简单的数据透视表 增加一个行维度(inde ...

  6. 我们无法找到服务器加载工作簿的数据模型"的 SharePoint 网站,当您刷新 Excel 2013 工作簿中的数据透视表时出错

    假定您使用 Analysis Services 源在 Microsoft Excel 2013 中创建数据透视表.将 Excel 工作簿上载到 Microsoft SharePoint 网站中.当您尝 ...

  7. delphi 控制 EXCEL 数据透视表

    虽说报表多又难做,做报表相当容易. 做报表也可以偷懒的,超级实用又省事.只需要做一个报表,这个报表里面包括几乎所有的数据字段,然后将查询到的数据导出到 excel中,利用excel自带的“数据透视”功 ...

  8. C# 操作Excel数据透视表

    一.概述 数据透视表(Pivot Table)是一种交互式的表,可以进行某些计算,如求和与计数等,可动态地改变透视表版面布置,也可以重新安排行号.列标和页字段.当改变版面布置时,数据透视表也会按照新的 ...

  9. Excel如何快速统计一列中相同数值出现的个数--数据透视表

    excel如何快速统计一列中相同数值出现的个数_百度经验 --这里介绍了两种解决方式,用第一种https://jingyan.baidu.com/article/9113f81b2c16822b321 ...

随机推荐

  1. unigui下载文件

    lblProduct.Caption := '<a href="files\1.t" target=new>要下载的文件名</a>';

  2. windows程序员进阶系列:《软件调试》之堆 (一)

    windows程序员进阶系列:<软件调试>之堆 (一) 堆是软件在运行时动态申请内存空间的主要途径.从堆上申请来的空间需要程序员自己申请和释放,且申请和释放操作必须绝对匹配.忘记释放或者多 ...

  3. [html][转]常用返回顶部代码

    转至:http://jingyan.baidu.com/article/7082dc1ca6b928e40a89bd1a.html 一.使用HTML的锚标记最简单了 但是唯一的缺点就是样式不怎么样,会 ...

  4. Cookie与Session的初探

    1.Cookie 2.Session 每当一个新的请求来时,asp.net会根据浏览器有没传来SessionId(一般用Cookie传过来的,也可以用url传),来判断是新创建一个session还是根 ...

  5. Windows Azure Website类别、限制条件

    在Azure中Website是一个典型的SAAS,用户可以很容易地搭建自己想要的网站,可以基于多种编程语言(ASP.NET/ASP/PHP/Node.JS等)和网站框架. Website有三种分类分别 ...

  6. Moebius实现Sqlserver集群~介绍篇

    今年是一个不平凡的一年,接触到了很多新艳的,让人兴奋的东西,虽然自己的牙掉了两颗,但感觉自己又年青了两岁,哈哈!进入正题,今年公司开始启用数据库集群,对于Sqlserver来说,实现方式并不是很多,一 ...

  7. 将SCOM2007代理升级到 System Center 2012 SP1

    使用以下过程可以升级到 System Center 2012 Service Pack 1 (SP1), Operations Manager工程师.您应首先验证代理程序满足最小受支持的配置.有关详细 ...

  8. nonce和timestamp在Http安全协议中的作用

    前段时间给客户网站做新浪微博账号登录功能,对OAuth协议以及相关的一些安全协议做了一些研究,顺便就记录一下学习心得吧.在这里就不打算具体讲OAuth的协议流程了,而是针对OAuth请求头里的nonc ...

  9. Android Studio导入项目

    原文:http://ask.android-studio.org/?/article/21 本篇教程中使用到的Android Studio版本为1.0, Eclipse ADT版本23.0.4.请尝试 ...

  10. [Bootstrap] 1. container & container-fluid

    Container: 居中 <!DOCTYPE html> <html> <head> <title>Blasting Off With Bootstr ...