"来自HRESULT的异常:0x800A03EC"使用Excel OpenFile()时

时间:2018-03-09 17:59:33

标签: c# excel

每次尝试打开CSV文件(无论是.csv还是.txt)时,都会收到此异常。因为例外是如此通用,我无法弄清楚出了什么问题。

我的程序是一个Winform应用程序,它从IBM大型机FTP数据,解析它,并生成理想情况下在电子表格中查看的自定义对象,以便于导航和过滤。首先,我尝试将数据直接写入电子表格,但这对于大型数据集来说需要很长时间。例如,对于100个自定义对象,我的程序花了大约20秒将它们写入电子表格。我的最终用户需要为数千到数万个自定义对象创建电子表格并不罕见。由于我不希望用户在创建电子表格时闲置一小时,因此我查看了缓慢的原因。我在StackExchange上读到Interop.Excel指令非常慢,所以为了限制它们的数量,我尝试了另一种解决方案:首先我将数据写入CSV,然后我使用Interop.Excel来打开CSV,也许做一些轻微的格式化,如着色标题和冻结顶行,然后保存为.xls或.xlsx。但是我在第一步遇到麻烦:打开CSV!

以下是代码:

using Excel = Microsoft.Office.Interop.Excel;

...

private void BuildSpreadsheetFromCsvFiles(string spreadsheetPath, string csvPathTrimmedTranlog, string csvPathFullTranlog)
{
    Excel.Application xlApp = new Excel.Application();

    try
    {
        // Set up the arrays of XlColumnDataTypes
        Excel.XlColumnDataType[] trimmedDataTypes = new Excel.XlColumnDataType[trimmedTranlog.TagsPresent.Count];
        Excel.XlColumnDataType[] fullDataTypes = new Excel.XlColumnDataType[fullTranlog.TagsPresent.Count];
        for(int i = 0; i < trimmedDataTypes.Length; i++)
        {
            trimmedDataTypes[i] = Excel.XlColumnDataType.xlTextFormat;
        }
        for(int i = 0; i < fullDataTypes.Length; i++)
        {
            fullDataTypes[i] = Excel.XlColumnDataType.xlTextFormat;
        }

        xlApp.Workbooks.OpenText(Filename: csvPathTrimmedTranlog,  // THROWS EXCEPTION
            Origin: Excel.XlPlatform.xlWindows,
            DataType: Excel.XlTextParsingType.xlDelimited,
            TextQualifier: Excel.XlTextQualifier.xlTextQualifierNone,
            Semicolon: true,
            FieldInfo: trimmedDataTypes);
        Excel.Workbook xlWorkbookTrimmed = xlApp.Workbooks[1];
        xlApp.Workbooks.OpenText(Filename: csvPathFullTranlog,  // ALSO THROWS EXCEPTION
            DataType: Excel.XlTextParsingType.xlDelimited,
            Origin: Excel.XlPlatform.xlWindows,
            TextQualifier: Excel.XlTextQualifier.xlTextQualifierNone,
            Semicolon: true,
            FieldInfo: fullDataTypes);
        Excel.Workbook xlWorkbookFull = xlApp.Workbooks[1];

        Excel.Worksheet xlWorksheetTrimmed = xlWorkbookTrimmed.Worksheets[1];
        Excel.Worksheet xlWorksheetFull = xlWorkbookFull.Worksheets[1];
        xlWorksheetTrimmed.Copy(Before: xlWorksheetFull);

        xlApp.Visible = true;
    }
    catch(Exception e)
    {
        xlApp.Quit();
    }
}

我尝试用Open()而不是OpenText()打开文件,这在技术上是有效的。但是,出于我的目的,我不能使用Open(),因为这样做所有列都将被读作通用格式。我的数据包含需要显示为文本的长串数字(大约20位),而Open()将显示带有科学记数法的数字。

更多信息:

  • 创建工作簿时,它将在Excel 2016中创建。
  • 我将.txt文件修剪为包含20行和6列,问题仍然存在。
  • .txt文件可以在Excel 2016中手动打开,但不能在我的Winform应用程序中以编程方式打开。

更新 我已将问题缩小到OpenText()中的最后一个参数FieldInfo:参数。省略该参数后,文件将成功打开。不幸的是,正如我之前所说,数据必须格式化为Text,而不是默认的General。

1 个答案:

答案 0 :(得分:0)

问题是FieldInfo参数。根据{{​​3}}:

  

当数据分隔时,此参数是一个包含两个元素的数组   数组,每个双元素数组指定转换选项   对于特定的列。第一个元素是列号   (基于1),第二个元素是X1ColumnDataType之一   指定如何解析列的常量。

我在原始代码中重写了“设置XlColumnDataTypes的数组”部分,现在它按预期工作。

// Set up the arrays of XlColumnDataTypes
int[,] trimmedDataTypes = new int[trimmedTranlog.TagsPresent.Count, 2];
for(int i = 1; i <= trimmedDataTypes.Length / 2; i++)
{
    trimmedDataTypes[i - 1, 0] = i;
    trimmedDataTypes[i - 1, 1] = (int)Excel.XlColumnDataType.xlTextFormat;
}
int[,] fullDataTypes = new int[fullTranlog.TagsPresent.Count, 2];
for(int i = 1; i <= fullDataTypes.Length / 2; i++)
{
    fullDataTypes[i - 1, 0] = i;
    fullDataTypes[i - 1, 1] = (int)Excel.XlColumnDataType.xlTextFormat;
}