在做项目中遇见了这种情况:
需要在Excel某些内容已经存在的情况下,去套用这个“模板” 进行生成Excel 文件
同时服务器又不能开启任何Excel进程,
我的解决方案就是将其当作xml 进行处理:
首先,将基础的Excel(即含有初始内容的模板Excel) 保存至XML形式之后,读取这个xml 节点,接着在节点上放东西,就可以了 说起来比较简单,但是操作起来比较恶心,主要是因为xml的命名空间导致的
如果你新建节点但是不指名命名空间的话,XElement 竟然会把xmlns 置空了,这样excel 在读取这个节点的时候就会因为命名空间不是指定的空间而忽略这个节点。
详细信息如下所示
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ReadXml();
}
public static void ReadXml()
{
string xmlFile = @"d:\my documents\visual studio 2010\Projects\Cookbook\ConsoleApplication1\XMLFile1.xml";
XElement root = XElement.Load(xmlFile);
DataTable t = new DataTable();
t.Columns.Add();
t.Columns.Add();
var dr = t.NewRow();
dr[0] = "测试1";
dr[1] = "测试结果1";
t.Rows.Add(dr);
var dr2 = t.NewRow();
dr2[0] = "测试2";
dr2[1] = "测试结果2";
t.Rows.Add(dr2);
var ds = new DataSet();
ds.Tables.Add(t);
InsertDataToExcelXml(ds, root);
root.Save("tmp.xml");
string str = File.ReadAllText("tmp.xml");
Console.WriteLine(str);
Console.ReadLine();
}
public static void InsertDataToExcelXml(DataSet ds, XElement ExcelRoot)
{
List<XElement> list = new List<XElement>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
var row = new XElement(ExcelRoot.GetDefaultNamespace() + "Row", new XAttribute(ExcelRoot.GetNamespaceOfPrefix("ss") + "AutoFitHeight", 0));
var col = 1;
foreach (DataColumn dc in ds.Tables[0].Columns)
{
var column = new XElement(ExcelRoot.GetDefaultNamespace() + "Cell", new XAttribute(ExcelRoot.GetNamespaceOfPrefix("ss") + "Index", col),
new XElement(ExcelRoot.GetDefaultNamespace() + "Data", new XAttribute(ExcelRoot.GetNamespaceOfPrefix("ss") + "Type", "String"),
new XText(dr[dc].ToString())
)
);
row.Add(column);
col++;
}
list.Add(row);
}
//此处的4 的意思是第一张sheet 表 ,前三个节点Excel用来保存的其他信息,sheet表从4号开始
ExcelRoot.ElementList()[4].ElementList()[0].SetAttributeValue(
ExcelRoot.GetNamespaceOfPrefix("ss") + "ExpandedRowCount",
(int.Parse(
ExcelRoot.ElementList()[4].ElementList()[0].Attribute(ExcelRoot.GetNamespaceOfPrefix("ss") + "ExpandedRowCount").Value.ToString()
) + list.Count())
);
ExcelRoot.ElementList()[4].ElementList()[0].Elements(XName.Get("Row", "urn:schemas-microsoft-com:office:spreadsheet")).Last().AddAfterSelf(list);
}
}
public static class XElementEntension
{
public static List<XElement> ElementList(this XElement element)
{
return element.Elements().ToList();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ReadXml();
}
public static void ReadXml()
{
string xmlFile = @"d:\my documents\visual studio 2010\Projects\Cookbook\ConsoleApplication1\XMLFile1.xml";
XElement root = XElement.Load(xmlFile);
DataTable t = new DataTable();
t.Columns.Add();
t.Columns.Add();
var dr = t.NewRow();
dr[0] = "测试1";
dr[1] = "测试结果1";
t.Rows.Add(dr);
var dr2 = t.NewRow();
dr2[0] = "测试2";
dr2[1] = "测试结果2";
t.Rows.Add(dr2);
var ds = new DataSet();
ds.Tables.Add(t);
InsertDataToExcelXml(ds, root);
root.Save("tmp.xml");
string str = File.ReadAllText("tmp.xml");
Console.WriteLine(str);
Console.ReadLine();
}
public static void InsertDataToExcelXml(DataSet ds, XElement ExcelRoot)
{
List<XElement> list = new List<XElement>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
var row = new XElement(ExcelRoot.GetDefaultNamespace() + "Row", new XAttribute(ExcelRoot.GetNamespaceOfPrefix("ss") + "AutoFitHeight", 0));
var col = 1;
foreach (DataColumn dc in ds.Tables[0].Columns)
{
var column = new XElement(ExcelRoot.GetDefaultNamespace() + "Cell", new XAttribute(ExcelRoot.GetNamespaceOfPrefix("ss") + "Index", col),
new XElement(ExcelRoot.GetDefaultNamespace() + "Data", new XAttribute(ExcelRoot.GetNamespaceOfPrefix("ss") + "Type", "String"),
new XText(dr[dc].ToString())
)
);
row.Add(column);
col++;
}
list.Add(row);
}
//此处的4 的意思是第一张sheet 表 ,前三个节点Excel用来保存的其他信息,sheet表从4号开始
ExcelRoot.ElementList()[4].ElementList()[0].SetAttributeValue(
ExcelRoot.GetNamespaceOfPrefix("ss") + "ExpandedRowCount",
(int.Parse(
ExcelRoot.ElementList()[4].ElementList()[0].Attribute(ExcelRoot.GetNamespaceOfPrefix("ss") + "ExpandedRowCount").Value.ToString()
) + list.Count())
);
ExcelRoot.ElementList()[4].ElementList()[0].Elements(XName.Get("Row", "urn:schemas-microsoft-com:office:spreadsheet")).Last().AddAfterSelf(list);
}
}
public static class XElementEntension
{
public static List<XElement> ElementList(this XElement element)
{
return element.Elements().ToList();
}
}
}
此方法的优点为不用打开Excel 进程,纯粹用xml 解决问题