我的整体问题是我有一个大型Excel文件(列A-S,85000行),我想将其转换为XML。单元格中的数据都是文本。
我现在使用的过程是手动将excel文件保存为csv,然后在我自己的c#程序中解析它以将其转换为XML。如果您有更好的建议,请推荐。我搜索了SO,我发现直接转换为XML的唯一 fast 方法要求我的数据都是数字的。 (逐个细胞读取细胞,需要3天才能处理)
因此,除非您能为我推荐一种不同的解决方法,否则我希望能够以编程方式从excel表中删除所有逗号,<,>,'和“。
答案 0 :(得分:2)
有许多选项可供阅读/编辑/创建Excel文件:
MS提供免费的OpenXML SDK V 2.0 - 请参阅http://msdn.microsoft.com/en-us/library/bb448854%28office.14%29.aspx(仅限XLSX)
这可以读取+写入MS Office文件(包括Excel)。
另一个免费选项见http://www.codeproject.com/KB/office/OpenXML.aspx(仅限XLSX)
如果你需要更多像处理旧的Excel版本(如XLS,不仅仅是XLSX),渲染,创建PDF,公式等,那么有不同的免费和商业库,如ClosedXML(免费,仅限XLSX), EPPlus(免费,仅限XLSX),Aspose.Cells,SpreadsheetGear,LibXL和Flexcel等。
另一个选项是Interop,它要求在本地安装Excel但Interop is not supported in sever-scenarios by MS。
根据我的经验,任何基于库的直接处理Excel文件的方法都比Interop快......
答案 1 :(得分:1)
我会使用Microsoft.Office.Interop.Excel
和XmlSerializer
的组合来完成工作。
这是因为a)您正在使用控制台应用程序,以及b)互操作程序集很容易集成到解决方案中(只需 References-> Add )。
我假设您在运行该过程的机器中安装了Excel副本(您提到您当前手动打开工作簿,因此假设)。
代码看起来像这样:
可序列化层:
public class TestClass
{
public List<TestLineItem> LineItems { get; set; }
public TestClass()
{
LineItems = new List<TestLineItem>();
}
}
public class TestLineItem
{
private string SanitizeText(string input)
{
return input.Replace(",", "")
.Replace(".", "")
.Replace("<", "")
.Replace(">", "")
.Replace("'", "")
.Replace("\"", "");
}
private string m_field1;
private string m_field2;
public string Field1
{
get { return m_field1; }
set { m_field1 = SanitizeText(value); }
}
public string Field2
{
get { return m_field2; }
set { m_field2 = SanitizeText(value); }
}
public decimal Field3 { get; set; }
public TestLineItem() { }
public TestLineItem(object field1, object field2, object field3)
{
m_field1 = (field1 ?? "").ToString();
m_field2 = (field2 ?? "").ToString();
if (field3 == null || field3.ToString() == "")
Field3 = 0m;
else
Field3 = Convert.ToDecimal(field3.ToString());
}
}
然后打开工作表并加载到2D数组:
// using OExcel = Microsoft.Office.Interop.Excel;
var app = new OEXcel.Application();
var wbPath = Path.Combine(
Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments), "Book1.xls");
var wb = app.Workbooks.Open(wbPath);
var ws = (OEXcel.Worksheet)wb.ActiveSheet;
// there are better ways to do this...
// this one's just off the top of my head
var rngTopLine = ws.get_Range("A1", "C1");
var rngEndLine = rngTopLine.get_End(OEXcel.XlDirection.xlDown);
var rngData = ws.get_Range(rngTopLine, rngEndLine);
var arrayData = (object[,])rngData.Value2;
var tc = new TestClass();
// since you're enumerating an array, the operation will run much faster
// than reading the worksheet line by line.
for (int i = arrayData.GetLowerBound(0); i <= arrayData.GetUpperBound(0); i++)
{
tc.LineItems.Add(
new TestLineItem(arrayData[i, 1], arrayData[i, 2], arrayData[i, 3]));
}
var xs = new XmlSerializer(typeof(TestClass));
var fs = File.Create(Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"Book1.xml"));
xs.Serialize(fs, tc);
wb.Close();
app.Quit();
生成的XML输出将类似于:
<TestClass>
<LineItems>
<TestLineItem>
<Field1>test1</Field1>
<Field2>some&lt;encoded&gt; stuff here</Field2>
<Field3>123456.789</Field3>
</TestLineItem>
<TestLineItem>
<Field1>test2</Field1>
<Field2>testing some commas, and periods.</Field2>
<Field3>23456789.12</Field3>
</TestLineItem>
<TestLineItem>
<Field1>test3</Field1>
<Field2>text in &quot;quotes&quot; and &#39;single quotes&#39;</Field2>
<Field3>0</Field3>
</TestLineItem>
</LineItems>
</TestClass>