Open xml 操作Excel 透视表(Pivot table)-- 实现Excel多语言报表
我的一个ERP项目中,客户希望使用Excel Pivot table 做分析报表。 ERP 从数据库中读出数据,导出到Excel中的数据源表(统一命名为Data),刷新Pivot table!
客户还希望对Excel报表提供多语言支持, 根据用户的语言生成不同版本的Excel文件。
经过不断尝试,终于成功完成该任务, 本篇简要描述这个任务涉及到的知识点。
把一个包含透视表及透视图的Excel .xlsx文件重命名为.zip 文件,然后解压缩到某个文件夹下,就可以看到Excel是如何定义透视表及透视图了, 如下图所示,pivotTables 定义了透视表中行、列及数据字段等, PivotCache 中则定义了Pivot table 的数据源、字段匹配,以及缓存了上一次打开的数据
(Excel文件结构)
(pivotTables\pivotTable1.xml截图)
(pivotCache\pivotCacheDefinition1.xml 截图)
根据以上描述, 在导入数据后. 还需要完成以下步骤:
- 重新设置透视表 的数据源到数据区域.
重新设置Pivot table 数据源的代码如下:
- //其中sheetName为作为数据源的工作表名,lastReference为数据源中最后一个单元格的引用名,比如最后一列为AG,共10行则为AG10
- public static void SetPivotSource(WorkbookPart wbPart, string sheetName, string lastReference)
- {
- var pivottableCashes = wbPart.PivotTableCacheDefinitionParts;
- foreach (PivotTableCacheDefinitionPart pivottablecachePart in pivottableCashes)
- {
- pivottablecachePart.PivotCacheDefinition.CacheSource.RemoveAllChildren();
- //设置Pivot tabla的数据源为A1:lastReference
- pivottablecachePart.PivotCacheDefinition.CacheSource.Append(new WorksheetSource() {
- Sheet = sheetName, Reference = new StringValue("A1:" + lastReference) });
- }
- }
- //假设Data表格中的最后一列的Reference为AG,总共有100行(加上列头行共101行),则导入数据后调用
- using (SpreadsheetDocument document = SpreadsheetDocument.Open(rawFileName, true))
- {
- WorkbookPart wbPart = document.WorkbookPart;
- SetPivotSource(wbPart,"data","AG101");
- }
2. 翻译Excel 数据源表字段名
也就是翻译及修改Data表格中第一行的单元格内容
- public static void UpdateCellValue(WorkbookPart wbPart, Cell theCell,string newValue)
- {
- string value = theCell.InnerText;
- if (theCell.DataType != null)
- {
- switch (theCell.DataType.Value)
- {
- case CellValues.SharedString:
- var stringTable = wbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
- if (stringTable != null)
- {
- var ele = stringTable.SharedStringTable.ElementAt(int.Parse(value));
- ele.RemoveAllChildren();
- ele.Append(new DocumentFormat.OpenXml.Spreadsheet.Text(newValue));
- }
- break;
- case CellValues.Boolean:
- if (string.Compare(value,"FALSE",true) ==)
- {
- theCell.InnerXml = "";
- }
- else
- {
- theCell.InnerXml = "";
- }
- break;
- default:
- theCell.InnerXml = newValue;
- break;
- }
- }
- }
- using (SpreadsheetDocument document = SpreadsheetDocument.Open(rawFileName, true))
- {
- WorkbookPart wbPart = document.WorkbookPart;
- var dataSheet = wbPart.Workbook.Descendants<Sheet>().FirstOrDefault(c => string.Compare(c.Name, "Data",true)==);
- WorksheetPart worksheetPart = (WorksheetPart)wbPart.GetPartById(dataSheet.Id);
- var headerRow = worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>().
- FirstOrDefault(c => c.RowIndex == );
- var cells = headerRow.Elements<Cell>().ToList();
- foreach (var cell in cells)
- {
- var rawText = ExcelHelper.GetCellValue(wbPart, cell);
- ExcelHelper.UpdateCellValue(wbPart, cell, _translator.Translate(rawText));
- //cell.CellValue = new CellValue(_translator.Translate(rawText));
- //cell.DataType = new EnumValue<CellValues>(CellValues.String);
- }
- worksheetPart.Worksheet.Save();
- }
3. 翻译pivotCacheDefinition缓存区的字段定义。
- using (SpreadsheetDocument document = SpreadsheetDocument.Open(rawFileName, true))
- {
- WorkbookPart wbPart = document.WorkbookPart;
- var pivottableCashes = wbPart.PivotTableCacheDefinitionParts;
- foreach (PivotTableCacheDefinitionPart pivottablecachePart in pivottableCashes)
- {
- pivottablecachePart.PivotCacheDefinition.RefreshOnLoad = true;
- var pivotCacheFields = pivottablecachePart.PivotCacheDefinition.CacheFields;
- foreach (OpenXmlElement pivotCacheField in pivotCacheFields)
- {
- OpenXmlAttribute nameEle = pivotCacheField.GetAttribute("name", "");
- nameEle.Value = _translator.Translate(nameEle.Value);
- pivotCacheField.SetAttribute(nameEle);
- }
- }
- }
4. 翻译Pivot Table 透视表定义区域的数据字段名,以及图表区的数据源表名
- //sheet为Sheet类型对象
- oxPart = wbPart.GetPartById(sheet.Id);
- //Translate Pivot table data(numeric) field defination, such as "Sum of [Vat...]"
- if (oxPart.ContentType.Contains("worksheet"))
- {
- wsP = (WorksheetPart)oxPart;
- tbDefParts = wsP.PivotTableParts;
- foreach (PivotTablePart ptPart in tbDefParts)
- {
- dataFileds = ptPart.PivotTableDefinition.DataFields;
- foreach (DataField df in dataFileds)
- {
- if (df.Name.Value.StartsWith(SUM_OF))
- {
- df.Name = new StringValue(_translator.Translate(SUM_OF) + " " +
- _translator.Translate(df.Name.Value.Replace(SUM_OF, "").Trim()));
- }
- }
- }
- }
- var index = rawFileName.LastIndexOf(@"\");
- var filename = rawFileName.Substring(index+);
- foreach(ChartsheetPart cspart in wbPart.ChartsheetParts)
- {
- var chartparts = cspart.DrawingsPart.ChartParts ;
- foreach(ChartPart cp in chartparts)
- {
- PivotSource pivotSource = cp.RootElement.OfType<PivotSource>().First();
- string originalName = pivotSource.PivotTableName.InnerText;
- Regex reg = new Regex(@"^[[]([^]]+)[]]([^!]+)!(.*)$");
- var matches = reg.Matches(originalName);
- if (matches.Count > && matches[].Groups.Count >)
- {
- string newName = string.Format("[{0}]{1}!{2}", filename,
- _translator.Translate(matches[].Groups[].Value), matches[].Groups[].Value);
- pivotSource.PivotTableName = new PivotTableName(newName);
- }
- }
5. 翻译表格名, 需要翻译所有除了Data表外的工作表名。
- foreach (Sheet sheet in sheets)
- {
- if (string.Compare(sheet.Name, "data", true) != )
- {
- var translatedName = _translator.Translate(sheet.Name);
- if (!string.IsNullOrEmpty(translatedName) && translatedName.Length > )
- {
- translatedName = translatedName.Substring(, );
- }
- sheet.Name = translatedName;
- }
- }
Open xml 操作Excel 透视表(Pivot table)-- 实现Excel多语言报表的更多相关文章
- (三、四)Superset 1.3图表篇——透视表-Pivot Table
本系列文章基于Superset 1.3.0版本.1.3.0版本目前支持分布,趋势,地理等等类型共59张图表.本次1.3版本的更新图表有了一些新的变化,而之前也一直没有做过非常细致的图表教程. 而且目前 ...
- Excel透视表进阶之计算字段、计算项、切片器、页面布局
计算字段 在透视表的字段列表中通过函数.公式等方式构建一个新的字段 又称虚拟字段,因为计算字段不会出现在数据源中,对于普通字段的操作,都可以对计算字段进行操作 计算字段只能出现在值区域,不能出现在筛选 ...
- html table表格导出excel的方法 html5 table导出Excel HTML用JS导出Excel的五种方法 html中table导出Excel 前端开发 将table内容导出到excel HTML table导出到Excel中的解决办法 js实现table导出Excel,保留table样式
先上代码 <script type="text/javascript" language="javascript"> var idTmr; ...
- SSAS多维设计模型与报表客户端-Excel透视表制作
VS:SSAS设计多维设计模型: 数据源视图.dsv: 数据源视图表,名称命名规范:vw_表名(事实表_F_/维表_D_),
- Excel透视表基础之数据源、创建、基本术语、基本操作
数据源的基本要求: 每列数据的第一行包含该列标题 不能包含空行或空列 不能包含空单元格 不能包含合并单元格 不能包含同类字段 如果包含空行.空列则删除空行和空列.如果包含空单元格则填充空单元格. 如果 ...
- Java 创建、刷新Excel透视表/设置透视表行折叠、展开
透视表是依据已有数据源来创建的交互式表格,我们可在excel中创建透视表,也可编辑已有透视表.本文以创建透视表.刷新透视表以及设置透视表的行展开或折叠为例,介绍具体的操作方法. 所需工具:Free S ...
- Excel透视表基础之字段布局与重命名、更新、数字格式设置、空值与错误值、
字段布局与重命名 经典布局切换 字段布局 默认布局:文本类型在行区域.数字类型在值区域. 最好用鼠标拖拽. 字段重命名 可以在字段设置中更改. 透视表更新 延迟更新 手动刷新 自动刷新 刷新注意事项 ...
- Excel透视表进阶之排序、筛选、分组、总计与分类汇总
排序 自动排序 升序: 数字(从小到大) 日期(日期越早越靠小) 英文(按照A-Z) 中文(按照拼音的A-Z) 手动排序 通过鼠标的拖拽来完成手动排序 通过快捷菜单的方式:右击-移动 依据其他字段进行 ...
- 2018.03.29 python-pandas 数据透视pivot table / 交叉表crosstab
#透视表 pivot table #pd.pivot_table(data,values=None,index=None,columns=None, import numpy as np import ...
随机推荐
- [No000099]软件版本命名规范
软件版本阶段说明 Base: 此版本表示该软件仅仅是一个假页面链接,通常包括所有的功能和页面布局,但是页面中的功能都没有做完整的实现,只是做为整体网站的一个基础架构. Alpha: 此版本表示该软件在 ...
- Nginx支持比Apache高并发的原因
1.先从各自使用的多路复用IO模型说起: select模型:(apache使用,由于受模块等限制,用的不多) 单个进程能够 监视的文件描述符的数量存在最大限制 select()所维护的 存储大量 ...
- Weekly Traning Farm 16
先安利一下这套比赛,大概是doreamon搞的,每周五晚上有一场,虽然没人做题目质量挺高的 http://codeforces.com/group/gRkn7bDfsN/contests(报名前要先报 ...
- 转 jQuery 中bind(),live(),delegate(),on() 区别
当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...
- [LeetCode] Top K Frequent Elements 前K个高频元素
Given a non-empty array of integers, return the k most frequent elements. For example,Given [1,1,1,2 ...
- 【VS】vs修改大小写快捷键
选中一段英文 改成小写:Ctrl+U 改成大写:Ctrl+Shift+U
- linux下查看最消耗CPU、内存的进程
2012-11-19 15:38:04 分类: LINUX 1.CPU占用最多的前10个进程: ps auxw|head -1;ps auxw|sort -rn -k3|head -10 2.内存消耗 ...
- Leetcode 69. Sqrt(x)
Implement int sqrt(int x). 思路: Binary Search class Solution(object): def mySqrt(self, x): "&quo ...
- CUDA[2] Hello,World
Section 0:Hello,World 这次我们亲自尝试一下如何用粗(CU)大(DA)写程序 CUDA最新版本是7.5,然而即使是最新版本也不兼容VS2015 ...推荐使用VS2012 进入VS ...
- AngularJS +HTML Demo
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...