----Lixg [email protected]
Ecma Office Open XML(“Open XML”)是针对字处理文档、演示文稿和电子表格的国际化开放标准。(话说中文资料好少)
想看到***.xlsx文档内部是怎么存储信息是很简单的,只需要将***.xlsx后缀名改为***.zip,然后用压缩软件解压缩就得到了一堆xml文件,而各公司就是利用openxml的标准解析,存储一个表格。所以想了解OpenXML需要先了解xml文件。
示例 li.xlsx解压结果(主目录,及xl子目录和 worksheets子目录)
----------------------------------------------------------------------------------------------------------------------------------------------------
下边介绍microsoft提供的SpreadsheetDocument类,操作excel文档(文末代码):
SpreadsheetDocument:
表格文档类
WorkbookPart:
对应workbook.xml文档建立的一个类,处理该文档与外部的关系。
Workbook:
对应workbook.xml中的workbook元素。存储一excel文档的各sheet表的索引信息。
Sheets:
对应workbook的sheets子元素,包含所有sheet表的索引信息。
Sheet:
对应sheets的sheet子元素,包含一个sheet表的名称,及索引信息。可以由r:id 获取与该sheet对应的WorksheetPart对象。
Workbook.xml 示例
WorksheetPart:
对应sheet*.xml文档建立的一个类,处理该文档与外部的关系。
Worksheet:
对应sheet*.xml中的worksheet元素。存储一个sheet表的所有数据。
SheetData:
对应Worksheet的sheeData子元素,包含sheet表的所有 row(行)及单元格数据。
Row:
对应sheetData的Row子元素,sheet表中一行。
Cell:
对应Row的c子元素,sheet表中的一个单元格,存储一个数据。
Sheet*.xml示例:
////// 代码君来了//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace COpenXML
{
class clsExcel
{
/***** All Open Items ******/
public Sheets m_Sheets; // Sheets : WorkBook 子项,各Sheet集合
public Workbook m_WorkBook; // WorkBook : WorkBook.xml的子项 存储*xlsx的相关信息
public WorkbookPart m_WorkBookPart; // WorkBookpart : WorkBook容器
public SharedStringTable m_ShareTable;
public Worksheet m_WorkSheet; // WorkSheet : sheet*.xml 的容器, 1对1的关系
public WorksheetPart m_WorkSheetPart; // WorkSheetPart : WorkSheet 的容器,从WorkBookPart获取
public SpreadsheetDocument m_Doc;
//===Summary===
//====================================
// Name : Lixg
// Date : 2013-11-26
// Func : 构造函数
//====================================
public clsExcel()
{
m_Sheets = null;
m_WorkSheet = null;
m_WorkSheetPart = null;
m_WorkBook = null;
m_WorkBookPart = null;
m_Doc = null;
}
//===Summary===
//====================================
// Name : Lixg
// Date : 2013-11-26
// Func : 关闭 Excel 文档
//====================================
public bool Close()
{
try
{
m_Doc.Close();
m_WorkSheet = null;
m_WorkSheetPart = null;
m_Sheets = null;
m_WorkBook = null;
m_WorkBookPart = null;
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
}
m_Doc = null;
return true;
}
//===Summary===
//====================================
// Name : Lixg
// Date : 2013-11-26
// Func : 打开一个已存在的Excel文档
//====================================
public bool Open(string fileName, string sheetName)
{
try
{
/****************************** *.xlsx ******************************/
m_Doc = SpreadsheetDocument.Open(fileName, true);
/*************************** WorkBook.xml ***************************/
/******** 统计 WorkBook.xml 文档的信息: WorkBook,Sheets ************/
m_WorkBookPart = m_Doc.WorkbookPart; // workbook.xml 和 workbook.xml.rels
m_WorkBook = m_Doc.WorkbookPart.Workbook; // workbook.xml 根元素 workbook
m_Sheets = m_WorkBook.Descendants
m_ShareTable = m_WorkBookPart.SharedStringTablePart.SharedStringTable;
if (false == sheetOpen(sheetName))
{
m_Doc.Close();
return false;
}
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
return false;
}
return true;
}
//===Summary===
//====================================
// Name : Lixg
// Date : 2013-11-26
// Func : 创建一个新的Excel文档
//====================================
public bool Creat(string strPathName, string sheetname)
{
try
{
m_Doc = SpreadsheetDocument.Create(strPathName, SpreadsheetDocumentType.Workbook);
// WorkbookPart
m_WorkBookPart = m_Doc.AddWorkbookPart();
// Workbook
m_WorkBook = m_WorkBookPart.Workbook = new Workbook();
// Sheets
m_Sheets = m_WorkBook.AppendChild
// ShareTable
m_WorkBookPart.AddNewPart
m_ShareTable = m_WorkBookPart.SharedStringTablePart.SharedStringTable = new SharedStringTable();
if (false == sheetInsert(sheetname))
{
m_Doc.Close(); return false;
}
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
return false;
}
return true;
}
//===Summary===
//====================================
// Name : Lixg
// Date : 2013-11-27
// Func : 查找 Sheet
//====================================
public bool sheetOpen(string sheetName)
{
try
{
Sheet sheetA;
// 获取 已SheetName命名的 Sheet
if (null == (sheetA = m_Sheets.Descendants
{
return false; // 新建一个 sheet
}
m_WorkSheetPart = (WorksheetPart)(m_WorkBookPart.GetPartById(sheetA.Id)); // 根据 sheet ID find sheet*.xml
m_WorkSheet = m_WorkSheetPart.Worksheet; // sheet*.xml 根元素 worksheet
return true;
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
return false;
}
}
//===Summary===
//====================================
// Name : Lixg
// Date : 2013-11-27
// Func : Insert new Sheet
//====================================
public bool sheetInsert(string sheetName)
{
try
{
/************************ 添加新Worksheet **********************/
WorksheetPart newWorksheetPart = m_Doc.WorkbookPart.AddNewPart
newWorksheetPart.Worksheet = new Worksheet(new SheetData());
/************************ 添加新Sheet **************************/
uint sheetID = 1;
if (m_Sheets.Descendants
{
sheetID = m_Sheets.Descendants
}
Sheet newSheet = new Sheet()
{
Name = sheetName,
SheetId = sheetID,
Id = m_Doc.WorkbookPart.GetIdOfPart(newWorksheetPart),
};
m_Sheets.Append(newSheet);
/************************ 更新当前成员 *******************************/
m_WorkSheetPart = newWorksheetPart;
m_WorkSheet = m_WorkSheetPart.Worksheet;
m_WorkSheet.Save();
m_WorkBook.Save();
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
return false;
}
return true;
}
//===Summary===
//====================================
// Name : Lixg
// Date : 2013-11-27
// Func : 查找并返回 Cell
//====================================
public string ReadCell(string Col, int Row)
{
try
{
SheetData sheetData;
if(null == (sheetData = m_WorkSheet.GetFirstChild
{
return null;
}
// 获取 Row
Row RowA;
if(null == (RowA = sheetData.Descendants
{
return null;
}
// 获取 Cell
Cell CellA = RowA.Descendants
if (null == CellA) return null;
if (CellA.DataType == null)
{
return CellA.CellValue.InnerText;
}
else if(CellA.DataType == CellValues.String)
{
return CellA.CellValue.InnerText;
}
else if (CellA.DataType == CellValues.SharedString)
{
return m_ShareTable.ChildElements[Int32.Parse(CellA.CellValue.InnerText)].InnerText;
}
else
{
return CellA.CellValue.InnerText;
}
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
return null;
}
}
// 写单元格 Int
public bool WriteCell(string Col, int Row, int CellOBJ)
{
return WriteCell(Col, Row, CellOBJ.ToString(), CellValues.Number);
}
// 写单元格 string
public bool WriteCell(string Col, int Row, string CellOBJ)
{
return WriteCell(Col, Row, CellOBJ, CellValues.String);
}
//===Summary===
//=================================
// Name : Lixg
// Date : 2013-11-27
// Func : 编辑单元格
//=====================================================
// Para : ColumnName 列标识 A-Z
// RowIndex 行号 1 2 3 4 5 6
// ValueOBJ 单元格Value
// DataType 0: Int 1: String
//
// Desc : 编辑
// 不存在的单元格则添加后编辑,存在则直接编辑
//=====================================================
private bool WriteCell(string Col, int Row, String CellOBJ, CellValues CellValue)
{
try
{
string CellRef = Col + Row.ToString();
SheetData sheetData;
if (null == (sheetData = m_WorkSheet.GetFirstChild
{
return false;
}
// 获取 Row
Row RowA;
if (null == (RowA = sheetData.Descendants
{
RowA = new Row() {
RowIndex = (UInt32)Row
};
sheetData.AppendChild(RowA);
}
// 获取 Cell
Cell CellA;
if (null == (CellA = RowA.Descendants
{
CellA = new Cell();
RowA.AppendChild(CellA);
}
CellA.DataType = CellValue;
CellA.CellValue = new CellValue(CellOBJ);
CellA.CellReference = CellRef;
m_WorkSheet.Save();
m_WorkBook.Save();
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
return false;
}
return true;
}
//===Summary===
//=================================
// Name : Lixg
// Date : 2015-08-06
// Func : 导出单元格
//=====================================================
// Para : CellOBJ 保存数据的二维数组
//
// Desc : 将CellOBJ二维数组中的数据写入excel表格中
//
//=====================================================
public bool WriteCells(string[,] CellOBJ)
{
string[] Col = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
try
{
SheetData sheetData;
if (null == (sheetData = m_WorkSheet.GetFirstChild
{
return false;
}
int RowMax = CellOBJ.GetUpperBound(0)+1;
int ColMax = CellOBJ.GetUpperBound(1)+1;
// 第一维做列号
for (int i = 0; i < RowMax; i++)
{
Row
RowA = new Row() { RowIndex = (UInt32)(i+1) };
for (int k = 0; k < ColMax; k++)
{
Cell
CellA = new Cell();
CellA.DataType = CellValues.String;
CellA.CellValue = new CellValue(CellOBJ[i, k]);
CellA.CellReference = Col[k] + (i+1).ToString();
RowA.AppendChild(CellA);
}
sheetData.AppendChild(RowA);
}
m_WorkSheet.Save();
m_WorkBook.Save();
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
return false;
}
return true;
}
}
}