的例子截至目前,除了自己导出文件之外,我还没有找到任何更好的解决方案(CsvWriter
是一个自定义类,但很简单 - CsvWriter.WriteItems
需要可枚举的字符串,必要时引用它们,并在它们之外的csv文件中构建一行):
public static class CsvExporter {
public static void ExportWorksheet (
CsvWriter csvWriter,
Excel.Worksheet worksheet,
Action<int,int> reportProgressCallback = null
) {
foreach (var row in WorksheetToStrings (worksheet, reportProgressCallback))
csvWriter.WriteItems (row);
}
public static IEnumerable<IEnumerable<string>> WorksheetToStrings (
Excel.Worksheet worksheet, Action<int,int> reportProgressCallback = null
) {
var usedRange = worksheet.UsedRange;
return RangeToStrings (usedRange, reportProgressCallback);
}
public static IEnumerable<IEnumerable<string>> RangeToStrings (
Excel.Range range,
Action<int,int> reportProgressCallback = null
) {
if (reportProgressCallback == null)
reportProgressCallback = (line, total) => { };
int rowsTotal = range.Rows.Count;
int currentRow = 0;
foreach (var row in range.Rows) {
++currentRow;
reportProgressCallback (currentRow, rowsTotal);
var rowValues = (row as Excel.Range).Value2 as object;
foreach (
var convertedRow in
convertToEnumerableOfEnumerablesOfStrings (rowValues)
)
yield return convertedRow;
}
}
private static IEnumerable<IEnumerable<string>>
convertToEnumerableOfEnumerablesOfStrings (
object values
) {
return convertToEnumerableOfEnumerablesOfObjects (values)
.Select (
r => r.Select (
c => convertSingleValueToString (c)
)
);
}
private static IEnumerable<IEnumerable<object>>
convertToEnumerableOfEnumerablesOfObjects (
object values
) {
var ary = values as object [,];
if (ary != null)
return convertTwoDimAryToEnumerableOfEnumerablesOfObjects (ary);
var obj = values as object;
if (obj != null)
return Enumerable.Repeat<IEnumerable<object>> (
Enumerable.Repeat<object> (obj, 1), 1
);
return Enumerable.Empty<IEnumerable<object>>();
}
private static IEnumerable<IEnumerable<object>>
convertTwoDimAryToEnumerableOfEnumerablesOfObjects (
object [,] ary
) {
var firstUpperBound = ary.GetUpperBound (0);
var secondUpperBound = ary.GetUpperBound (1);
return Enumerable.Range (1, firstUpperBound).Select (
i => Enumerable.Range (1, secondUpperBound).Select (j => ary [i, j])
);
}
private static string convertSingleValueToString (object value) {
if (value == null) {
return string.Empty;
} else if (value is string) {
return value as string;
} else if (value is long) {
return ((long) value).ToString (CultureInfo.InvariantCulture);
} else if (value is double) {
return ((double) value).ToString (CultureInfo.InvariantCulture);
} else if (value is bool) {
return (bool) value ? "TRUE" : "FALSE";
} else {
return value.ToString();
}
}
}
xlsx有什么问题?这很复杂,但是它有像EPPLUS这样的解决方案,它可以读/写xlsx,甚至支持LINQ。 对于CSV:Excel存储没有关于此的元数据,所以这将很难猜测国家 – 2013-02-20 09:33:14
我会建议使用一些其他文件格式比CSV。我知道这不是一个真正的答案,但当遇到像1,233.44(!)这样的数字时,CSV文件当然会给你带来麻烦。你的用户可以向你发送工作簿吗?甚至制表符分隔的文本文件会更好。 – 2013-02-20 12:39:33
如果我让Excel生成制表符分隔的文本文件,难道我没有同样的问题吗? – JohnB 2013-02-20 12:56:31