关于XML,之前解析过电文收发方面的,就是所谓的带表头、前缀(命名空间)SOAP格式。这次需求是解析一个xml的模板(xls内容),然后填充数据,最后保存。需要时可转换xls、pdf等文件。关于这种带属性xml文件, 只要了解linq操作的方法, 在參照微软官网上有样例,XAttribute类就是定义属性。基本上多数都可以解决。详细方法,随笔XML分类中,介绍的比较详细,至于今天要介绍的xls内容的xml文件的解析,以及创建节点也不在分篇,大致介绍下整体的思路。

比如其中某个定义表节点:

  <cto:Worksheet cto:Name="工作表1">
<cto:Table cto:ExpandedColumnCount="12" cto:ExpandedRowCount="3" x:FullColumns="1"
x:FullRows="1" cto:DefaultColumnWidth="54" cto:DefaultRowHeight="16.5">
<cto:Column cto:Width="69.75" />
<cto:Column cto:AutoFitWidth="0" cto:Width="84" />
<cto:Column cto:AutoFitWidth="0" cto:Width="66" />
<cto:Column cto:Width="69.75" />
<cto:Column cto:Index="6" cto:Width="69.75" cto:Span="1" />
<cto:Column cto:Index="8" cto:Width="57" />
<cto:Column cto:Width="69.75" />
<cto:Column cto:Width="71.25" />
<cto:Row cto:Height="17.25">
<cto:Cell cto:StyleID="s19"><cto:Data cto:Type="String">欄位1</cto:Data></cto:Cell>
<cto:Cell cto:StyleID="s18"><cto:Data cto:Type="String">欄位2</cto:Data></cto:Cell>
<cto:Cell cto:StyleID="s18"><cto:Data cto:Type="String">欄位3</cto:Data></cto:Cell>
<cto:Cell cto:StyleID="s18"><cto:Data cto:Type="String">欄位4</cto:Data></cto:Cell>
<cto:Cell cto:StyleID="s18"><cto:Data cto:Type="String">欄位5</cto:Data></cto:Cell>
</cto:Row>
<cto:Row>
<cto:Cell><cto:Data cto:Type="String">1001</cto:Data></cto:Cell>
<cto:Cell><cto:Data cto:Type="String">1002</cto:Data></cto:Cell>
<cto:Cell><cto:Data cto:Type="String">1003</cto:Data></cto:Cell>
<cto:Cell><cto:Data cto:Type="String">1004</cto:Data></cto:Cell>
<cto:Cell><cto:Data cto:Type="String">1005</cto:Data></cto:Cell>
</cto:Row>
</cto:Table>

这种xls类型的xml,用Linq来解析,和之前的Soap格式的并无二致,均是XElement 加载,命名空间+节点名 来获取集合,在通过栏位值、属性值等来获取到某个指定的节点,最后进行设置。

如想让栏位1 的值改成 列名1,操作如下

          XNamespace ss = @"xxxx...";
//獲取待賦值集合
var setcode = from d in xml.Descendants(cto + "Data")
select d;
//給固定表頭賦值
foreach (var item in setcode.ToList())
{
if (item.Value == "欄位1")
{
item.SetValue("列名1");
}
}

可见并没有任何质的改变,也就是所谓 命名空间+节点 格式,除此之外,该xml更多的定义了表的规范,长度,宽度,栏位行数、列数、节点属性(不可小看,后面会用到)之类的,看的人眼花缭乱。这种格式的xml,解析之后当然是往其中填充数据,比如从某表中导出某条件下的多笔数据,将其填充至此xml中。

仔细分析,该xml的表节点定义了一行列名,一行预览值,一般分两种情况:如果是单笔数据,那就是将预览行的值替换为表中捞取的数据;如果是多笔,从第三行开始,循环创建节点并赋值,最后将其节点插入预览行同级节点的下一个节点。其实没必要这样,直接循环组一个节点并赋值,然后插入预览行下放,最后删除预览行即可。

(ps:row 为读取DataTable行数)

                //创建节点
XElement addElement = null;
//填充节点
for (int i = ; i < row; i++)
{
addElement = new XElement(cto+ "Row",
new XElement(cto + "Cell",
new XAttribute(cto + "Index", ""),
new XElement(cto + "Data", new XAttribute(cto+ "Type", "String"), dt.Rows[i][])),
new XElement(cto + "Cell",
new XElement(cto+ "Data", new XAttribute(cto+ "Type", "String"), dt.Rows[i][])),
new XElement(cto+ "Cell",
new XElement(cto+ "Data", new XAttribute(cto+ "Type", "String"), dt.Rows[i][])),
new XElement(cto+ "Cell",
new XElement(ss + "Data", new XAttribute(cto+ "Type", "String"), dt.Rows[i][])),
new XElement(cto+ "Cell",
new XElement(cto+ "Data", new XAttribute(cto+ "Type", "String"), dt.Rows[i][]))
);
//插入數據
set.FirstOrDefault().AddAfterSelf(addElement);
}
//刪除預覽行
set.Remove();
//保存文件
xml.Save(newxmlPath);

写到这里,本以为XML已填充完成,实则不然,这里我也是踩到坑,后来将其xml转xls的时候,一直包失败,无法打开调用时的excle。网上有的说是WPS的锅,后来卸载,然后安装Office 又遇到了同样的错误。后来小组长中终于找到了其中的原因,是XML属性的锅!!! 前面提到xml定义表格的时候,指明了行数,cto:ExpandedRowCount=“3” ,这样当插入节点中的行数超过了这个设置值时,打开excle就会出错。问题原因就在这里。所以在插入节点之后保存xml之前,一定要重新设置其这个值,前面的方法已经介绍过如何设置值,这里就不在多说。

当将xml转换为xls格式的时候,方法有很多中,nopi 实际上是创建一个xls,然后按照一行一列的赋值,设置样式最后保存文件。对于本就是xls内容的xml使用nopi方法是十分愚蠢也是不可行的。总不能挨个解析其中xml的每个节点值和属性值,然后挨个在xls中赋值。其次还有 spire方式,这种方法是先去官网注册然后下载,安装,最后将安装文件中的dll添加至项目引用中,功能和强大,需要转xls就引用xls的dll,需要转pdf就引用pdf的dll 等等,代码也只需要三行,简洁又方便,CSDN中不少博主立推这种方法,我想说的是,这是一个坑,没错,就是一个坑,因为spire插件转xls 只支持200行,如果想要更多的话需要买会员!!!而且转PDF的时候,左下角会有水印之类的spire的标签以及官网地址...

对于此类Xml格式,以上两种均不可行,然后就剩下第三种,引用 Microsoft.Office.Interop.Excel 插件,写几行代码,原理大致就是,用本地的excle打开需要转换的xml,然后保存成xls格式。

不少园主对这种方法都有说明介绍,代码量也很少,这里就不贴了。毕竟转换格式这块我也是复制别人的代码。。。

对于转pdf格式,转换之后是分页的,比较纳闷,好好的一个表格,从中间切开,这种问题某度上面也是说法不一,当然是excle表长度的问题,不得不说还是小组长厉害,在茫茫xml中定义电子表格的时候,添加一个节点,设置纸张方向为横向 <Layout x:Orientation="Landscape"/>,在调节下边距大小即可满足pdf的标准产出。

谨以此文记录操作xls内容的xml文件时的一些方法以及坑

XML系列之--创建电文格式的XML(一)

XML系列之--解析电文格式的XML(二)

XML系列之--对电文格式XML的简单操作(三)

XML系列之--Linq操作带属性的XML(四)

---市人皆大笑,举手揶揄之

XML系列之--Linq操作带属性的XML(四)的更多相关文章

  1. C#使用Linq To XML读取XML,Linq生成XML,Linq创建带属性或带节点XML

    using System; using System.Linq; using System.Xml.Linq; namespace Sample2 { class Program { static v ...

  2. Linq to xml 操作带命名空间的xml

    昨天需要操作用代码操作csproj文件,实现不同vs版本的切换. 在用XElement读取了csproj文件以后怎么也获取不到想要的对象. 反反复复试验了好多次都不得要领:先看下csproj文件的内容 ...

  3. linq检索带命名空间的xml

    XElement el = XElement.Load(fil); XNamespace ns = "http://schemas.microsoft.com/ado/2009/11/edm ...

  4. Linq创建带命名空间、前缀、Soap格式的XML

    关于XML,我也是刚接触,关于一般常见的XML,博客园.CSDN上的资料很多,对于不常见的带命名空间.前缀.Soap格式的XML的描述相对来说寥寥无几,上一篇我写到了对相对复杂的XML的读操作,下面说 ...

  5. Linq解析带命名空间、前缀、Soap格式的XML

    关于XML,经常会用到,XML有一般的,同样也有二般的,更不要觉得会操作基础的XML就觉得自己已经精通XML操作,文中是对解析XML的方法进行介绍 1. 一般XML <?xml version= ...

  6. XML系列之--对电文格式XML的简单操作(三)

    前两章介绍了关于Linq创建.解析SOAP格式的XML,在实际运用中,可能会对xml进行一些其它的操作,比如基础的增删该查,而操作对象首先需要获取对象,针对于DOM操作来说,Linq确实方便了不少,如 ...

  7. XML系列之--创建电文格式的XML(一)

    关于XML,学校那会,老师在口中仅仅提及,自己也未曾深入接触过,仅是些将最基本XML文件内容显示在web定义的表格中之类的简单操作,如今项目中的收发电文涉及到复杂XML的操作.趁此契机好好回顾下XML ...

  8. XML系列之--解析电文格式的XML(二)

    上一节介绍了XML的结构以及如何创建.讲到了XML可作为一种简单文本存储数据,把数据存储起来,以XML的方式进行传递.当接收到XML时,必不可少的就是对其进行解析,捞取有效数据,或者将第三方数据以节点 ...

  9. xml文件的读写操作

    1.直接上代码:包含了xml文档的创建,读取xml文档,创建根节点,向根节点中添加子节点,保存xml文档----------先来张效果图: static void Main(string[] args ...

随机推荐

  1. React Native学习(一)——搭建开发环境

    第一次接触React Native,首先搭建环境,过程还算顺利,不过也遇到了些问题,这里简单记录下来.中文官网(http://reactnative.cn/docs/0.47/getting-star ...

  2. java_web学习(十) 显示mysql中的数据

    一.建立数据库 create database animal; create table animal( sno int, name varchar(20), weight varcahr(20), ...

  3. 【C#系列】浅谈委托和委托

    本篇文章更适合具有一定开发经验,一定功底,且对底层代码有所研究的朋友!!! 本篇文章主要采用理论和代码实例相结合方法来论述委托和事件,涉及到一些边界技术,如软件架构的OCP原则(开-闭原则), 软件架 ...

  4. DOM拓展表格小练习

    涉及的知识点 DOM操作HTML页面.DOM操控表格.一些基本的事件.遍历知识.数组字符串知识.函数的作用域知识 效果图 html代码 <body><div id="con ...

  5. linux数据库常用指令

    linux数据库环境搭建好之后,我们就可以创建数据库了,如果不是 很了解linux数据库环境搭建的话,可以到看看我上一篇文章linux数据库环境搭建 首先我们来创建一个数据库:使用指令sqlite3 ...

  6. CSS3中first-child、last-child、nth-child、nth-last-child

    1.单独指定第一个子元素.最后一个子元素的样式 <style type="text/css"> li:first-child{ background:yellow; } ...

  7. AtCoder Grand Contest 015

    传送门 A - A+...+B Problem 题意:n个数最大值a,最小值b,求和的可能数量. #include<cstdio> #include<algorithm> us ...

  8. 为什么ios手机安装好fiddler证书/charles证书还是抓不到https请求?

    为什么ios手机安装好fiddler证书/charles证书还是抓不到https请求? 最近有不少人有此困惑, 因为你的ios系统应该是10.0以上的系统, 在手机系统设置---关于手机----证书信 ...

  9. 狗书无敌,天下第一(flask基础)

    为什么选择使用flask? 和其他框架相比, Flask 之所以能脱颖而出,原因在于它让开发者做主,使其能对程序具有全面的创意控制. 在 Flask 中,你可以自主选择程序的组件,如果找不到合适的,还 ...

  10. Spring注解依赖注入的三种方式的优缺点以及优先选择

    当我们在使用依赖注入的时候,通常有三种方式: 1.通过构造器来注入: 2.通过setter方法来注入: 3.通过filed变量来注入: 那么他们有什么区别吗?应该选择哪种方式更好? 三种方式的区别小结 ...