Excel 电子表格文件格式,这种Excel和其他的Excel是不同的。他的本质上是一个Xml文件(用英文版的UtraEdit可以看到),所以他可以保存任何符号的字符,包括&(它在Xml文件中是一种特殊字符。所以用aspose等工具是不能读取这种字符的)。
反过来说,我们从中可以得到一种快速生成带有多个Worksheet的Workbook的Excel,从xml文件处理的个角度入手。
这是一个txt文件,也可以是一个xml文件,当我们把他的后缀名修改成.xls的时候,我们居然可以看到是一个带有两个worksheet的workbook的excel 文件
读取方式:
public class TableReader
{
private List
private TableParser _vTableParser = null;
public List
{
get { return _vlstDtDestination; }
}
public void Read(System.IO.StringReader strReader)
{
System.Xml.XmlReaderSettings xmlReaderSettings = CustomXmlReaderSetting.Create();
using (System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(strReader, xmlReaderSettings))
{
string currentNode = string.Empty;
string currentTableName = string.Empty;
KeyValuePair
while(xmlReader.Read())
{
if (xmlReader.NodeType == System.Xml.XmlNodeType.Element && xmlReader.Name == "Worksheet")
{
currentTableName = xmlReader.GetAttribute("ss:Name");
#region Test
if (currentTableName == "Rnc")
{
Console.WriteLine();
}
#endregion
if (currentTableName == "Info")
{
continue;
}
currentNode = xmlReader.ReadOuterXml();
currentPair=new KeyValuePair
Parse(currentPair);
currentPair = new KeyValuePair
}
}
}
}
#region Private's
private void Parse(KeyValuePair
{
if (_vTableParser==null)
{
_vTableParser = new TableParser(_vlstDtDestination);
}
_vTableParser.Parse(source);
}
#endregion
}
public class TableParser
{
private List
public TableParser(List
{
_vlstDtDestination = dtList;
}
public void Parse(KeyValuePair
{
if(source.Key.Trim()=="")
{
return;
}
System.Data.DataTable currentDt = null;
foreach(System.Data.DataTable dt in _vlstDtDestination)
{
if(dt.TableName==source.Key)
{
currentDt = dt;
}
}
if(currentDt==null)
{
currentDt = new System.Data.DataTable(source.Key);
_vlstDtDestination.Add(currentDt);
}
if(source.Value.Trim()=="")
{
return;
}
System.IO.StringReader reader = new System.IO.StringReader(source.Value);
System.Xml.XmlReaderSettings xmlReaderSettings = CustomXmlReaderSetting.Create();
using(System.Xml.XmlReader xmlReader=System.Xml.XmlReader.Create(reader,xmlReaderSettings))
{
System.Data.DataRow currentDr = null;
bool isValued = false;
bool isConstructed = false;
int index = 0;
while (xmlReader.Read())
{
switch (xmlReader.NodeType)
{
case System.Xml.XmlNodeType.Element:
if (xmlReader.Name == "Row")
{
if (isValued)
{
currentDt.Rows.Add(currentDr);
}
currentDr = currentDt.NewRow();
index = 0;
}
if (xmlReader.Name == "Data")
{
if (!isConstructed)
{
currentDt.Columns.Add(xmlReader.ReadString(), typeof(System.String));
}
else
{
currentDr[index++] = xmlReader.ReadString();
if (!isValued)
{
isValued = true;
}
}
}
break;
case System.Xml.XmlNodeType.EndElement:
if (xmlReader.Name == "Row" && !isConstructed)
{
isConstructed = true;
}
break;
}
}
if (isValued)
{
currentDt.Rows.Add(currentDr);
}
}
}
}
public class CustomXmlReaderSetting
{
public static System.Xml.XmlReaderSettings Create()
{
System.Xml.XmlReaderSettings xmlReaderSettings = new System.Xml.XmlReaderSettings();
xmlReaderSettings.ProhibitDtd = false;
xmlReaderSettings.CheckCharacters = false;
return xmlReaderSettings;
}
}
public class StreamFilter
{
public static System.IO.StringReader Filter(string path)
{
System.IO.FileStream fileStream = new System.IO.FileStream(
path,
System.IO.FileMode.Open,
System.IO.FileAccess.Read,
System.IO.FileShare.ReadWrite
);
StringBuilder builder = new StringBuilder();
fileStream.Seek(0,System.IO.SeekOrigin.Begin);
System.IO.StreamReader streamReader = new System.IO.StreamReader(fileStream);
for (string strLine = streamReader.ReadLine(); !streamReader.EndOfStream; strLine = streamReader.ReadLine())
{
strLine = strLine.Replace("&", "&");
builder.AppendFormat("{0}\n",strLine);
}
System.IO.StringReader strReader = new System.IO.StringReader(builder.ToString());
return strReader;
}
}
public class NameHandler
{
public static string ConvertName(string name)
{
string result = name.Trim();
result = Regex.Replace(result, "[^a-zA-Z\\d]", "_");
result = Regex.Replace(result, "_{2,}", "_");
if (result.StartsWith("_")) result = result.Substring(1, result.Length - 1);
if (result.EndsWith("_")) result = result.Substring(0, result.Length - 1);
return result;
}
}
The xml iteself is broken up into several major section:
Workbook:Root node of the xml,parent to all the other sections.
DocumentProperties:Most of the importation one sees when accessing File->Properties is defined here.
Styles:Formatting information defined here is available to different row,columns and specific cells in the worksheets.
Worksheet(s):As many worksheets as you want are defined here.
Worksheets consist of two major sections:
Table:This is where all visible data in the spreadsheet is stored.
WorksheetOptions:Global options for the worksheet itself.
Finally,the Table section defines two components:
Column
Row / Cell
With this information in hand one can plan out how to create the xml document that will then load into Microsoft Excel and look,feel and operate like a document created by sophisticate,loving user.
原文来自http://www.6excel.com/doc/20035转载请注明出处