4.使用Office Open XML SDK访问Excel2007数据表

MS要将Office Open XML 格式成为国际标准,实现一统江湖。MSOffice 格式开放,还是向好的方面发展。OOXMLSDK 2.0 将会在Office 2010版本正式发行,现使用Bata版本进行读写Excel2007

       说先俺的系统配置:

      系统:Windows Server 2003 R2 X64

      开发软件:Microsoft VS 2008 Team

Office版本:Excel2007

OOXML版本:Office Open XML SDK2.0 Bata

   关于OOXML的标准就不多说,先看看文件结构,单元格映射信息存放在部件tableSingleCells中,工作表信息存放在sheet,共享字符信息存放在sharedStrings

 

 

结构

 

使用到的主要部件将会有 xl/tables/tableSingleCells1.xmlxl/worksheets/sheet1.xml

 4.1建立XML映射:俺有这样一张表Book1.xlsx,想通过读取Excel数据,显示出来。

 

 

表格

 

俺想通过XML  MAP工作表的单元格,然后程序读取映射单元格中的值和Xpath。首先,建立映射关系,映射表中『用户名称』,『客户联系人』,『联系电话』,『客户经理』,『客户经理联系电话』,『业务类型』,『前端数量』,『业务类别』,『区域』字段值。第一步,要建立XML映射文件,T1schema.Xml映射文件如下:

<?xml version="1.0" standalone="yes"?>

<QQTintDataSet xmlns="http://tempuri.org/QQTintDataSet.xsd">

 <yyexcel>

    <id>1</id>

    <Customer></Customer>

    <CustomerContact></CustomerContact>

    <CustomerTelephone></CustomerTelephone>

    <AccountManager></AccountManager>

    <AMTelephone></AMTelephone>

    <AccessType></AccessType>

    <AccessAmount></AccessAmount>

    <BusinessName></BusinessName>

    <Regional></Regional>

  </yyexcel>

</QQTintDataSet>

    Excel2007“开发工具选项卡上的“XML”组中,单击。在“XML 任务窗格中,单击“XML 映射。添加T1schema.Xml映射文件, 确认后如图

 

XML映射源

拖动『ns1:Customer』到单元格『用户名称』,如此类推,建立XML映射

 

映射

 

关于Excel2007如何显示“XML源”按钮

http://office.microsoft.com/zh-cn/excel/HP102064082052.aspx

 

4.2 编写程序,读取单元格的值。新建一个控制台应用程序解决方案ConsoleApplication2,在ConsoleApplication2项目添加引用,引用为Office Open XML SDK2.0 Bata安装目录下DocumentFormat.OpenXml.dll文件,打开Program.cs,在文件头添加使用的库:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using DocumentFormat.OpenXml.Packaging;

using DocumentFormat.OpenXml.Spreadsheet;

using System.Text.RegularExpressions;

using System.IO.Packaging;

4.2.1创建一个方法,用于读取单元格的值,并返回其值。方法名称为getCellValue,参数依次为文件名,工作表名称,单元格名称。

  private static string getCellValue(string fileName, string sheetName, string addressName)

 

打开Excel2007文件,并取得相应的工作表

SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false);

IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName);

WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);

Worksheet worksheet = worksheetPart.Worksheet;

 

获取存在worksheetPart内部SingleCellTablePartxl/tables/tableSingleCells1.xml

SingleCellTablePart customxmlmap = worksheetPart.SingleCellTablePart;

获取符合条件的SingleXmlCell集合

IEnumerable<SingleXmlCell> singlexmlcells = customxmlmap.SingleXmlCells.Descendants<SingleXmlCell>();

获取每个SingleXmlCell

foreach (SingleXmlCell cellxmlmap in singlexmlcells)

  {

  获取xmlCellPr子树

  XmlCellProperties xmlcellp = cellxmlmap.XmlCellProperties;

 获取子树xmlPrXpath属性(映射Xpath)和单元格名称(XML属性r

 Console.WriteLine("单元格{1}映像信息:{0}", xmlcellp.XmlProperties.XPath, cellxmlmap.CellReference.Value);

  }

获取单元格行序号

uint rowIndex = GetRowIndex(addressName);

获取单元格列名称

string colName = GetColumnName(addressName);

根据行序号和列名称,得到单元格

Cell cell = GetSpreadsheetCell(worksheet, colName, rowIndex);

如果单元格是数字格式,在sheet.xml<v></v>直接表示单元格的值,所以直接返回,如表中单元格“I4”。

if (cell == null)

            {

                //指定的单元格不存在.

                return "找不到任何符合条件的单元格";

            }

            if (cell.DataType == null)

            {

                if (cell.CellValue != null)

                {

                    return cell.CellValue.Text;

                }

            }

如果单元格是字符格式或布尔格式,需要根据sheet.xmlt属性值转换。t=”s”表示字符,t=”b”表示布尔,

string str = "找不到任何符合条件的值";

            switch (cell.DataType.ToString())

            {

                case "s":

单元格的值是字符类型

                    SharedStringItem item;

                    SharedStringTablePart shareStringPart;

获取shareString部件

                    if (document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0)

                    {

                        shareStringPart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();

                        int requestedString = Convert.ToInt32(cell.CellValue.Text);

根据在sheet.xml<v></v>表示单元格的值,查找shareString获取相应字符。

                     item = shareStringPart.SharedStringTable.Elements<SharedStringItem>().ElementAt(requestedString);

                        str = item.Text.Text;

                    }

                    Console.WriteLine("单元格的类型是:S");

                    break;

                case "b":

单元格的值是布尔类型,根据在sheet.xml<v></v>表示单元格的值,转换成相应字符。

                    if (cell.CellValue.Text == "1")

                    {

                        str = "TRUE";

                    }

                    else

                    {

                        str = "FALSE";

                    }

                    Console.WriteLine("单元格的类型是:B");

                    break;

                default:

                    Console.WriteLine("单元格的类型是:{0}",cell.DataType);

                    break;

               

            }

4.2.2以上出现三个辅助函数,分别是GetRowIndexGetColumnNameGetSpreadsheetCell说明如下

 

// 创建正则表达式,根据单元格名称匹配行序号.

        private static uint GetRowIndex(string cellName)

        {           

            Regex regex = new Regex(@"/d+");

            Match match = regex.Match(cellName);

            return uint.Parse(match.Value);

        }

 

        // 根据单元格名称匹配列序号,从而得出单元格列序号.

        private static string GetColumnName(string cellName)

        {

            // 创建正则表达式,根据单元格名称匹配单元格列序号.

            Regex regex = new Regex("[A-Za-z]+");

            Match match = regex.Match(cellName);

            return match.Value;

        }

根据行列关系获取单元格

        private static Cell GetSpreadsheetCell(Worksheet worksheet, string columnName, uint rowIndex)

        {

            IEnumerable<Row> rows = worksheet.GetFirstChild<SheetData>().Elements<Row>().Where(r => r.RowIndex == rowIndex);

            if (rows.Count() == 0)

            {

                // 找不到匹配的行号.

                return null;

            }

 

            IEnumerable<Cell> cells = rows.First().Elements<Cell>().Where(c => string.Compare(c.CellReference.Value, columnName + rowIndex, true) == 0);

            if (cells.Count() == 0)

            {

                // 找不到匹配的单元格.

                return null;

            }

            return cells.First();

        }

4.2.3主过程如下:

       static void Main(string[] args)

        {

            string str = getCellValue("Book1.xlsx", "业务流程相关信息", "E4");

            Console.WriteLine("单元格的值是:{0}",str);

        }

4.2.4运行结果如下:

    getCellValue("Book1.xlsx", "业务流程相关信息", "I4");

 

 

 

结果一

   getCellValue("Book1.xlsx", "业务流程相关信息", "B3");

 

结果二

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值