【问题标题】:Saving HTML from MemoryStream into a Excel file将 MemoryStream 中的 HTML 保存到 Excel 文件中
【发布时间】:2025-12-01 11:15:01
【问题描述】:

我在 MemoryStream(C# 中)中有一个 XSLT 转换的 HTML 数据。我正在尝试在发送电子邮件之前将其转换为 Excel 格式,最好在不保存到本地磁盘的情况下再次在内存中进行转换。我可以稍后再担心电子邮件附件部分。谁能指出我如何通过 OpenXML 或 Office.Interop.Excel 将 HTML 格式转换为 Excel 格式的示例。

HTML 数据格式正确,我可以通过在 Excel 应用程序中打开 html 并执行另存为以将其保存为 xlsx 格式 (Office 2010) 来手动进行转换,没问题。我也尝试简单地将 .html 扩展名更改为 .xlsx,但随后 excel 抱怨打开它。

自动化手动 SaveAs 操作以便我可以使用 Excel 格式的相同 html 数据的最佳方法是什么?我知道我可以创建一个单独的 .xslt 来直接将我的 XML 转换为 Excel 格式。但是,要维护的 .xslt 太多了。我正在尝试找到让 Excel 为我完成工作的技巧。

感谢您提前提供的任何和所有指示!

编辑:

我想我别无选择,只能将 html 存储到磁盘并读回它并使用 Excel Interop 执行 SaveAs 方法。但是,当我尝试时,在 SaveAs 方法上使用 HRESULT: 0x800A03EC 获取异常。以下是如何重现它。

重现行为的步骤

  1. 保存此文本

<html><head></head><body><center><h1>Test Header</h1></center></body></html>

作为 C:\Test.html

  1. 像这样引用 Excel 互操作后,

使用 Excel = Microsoft.Office.Interop.Excel;

试试这个代码

` var app = new Excel.Application();

Excel.Workbook wb = null;

            try
            {
                wb = app.Workbooks.Open(@"c:\test.html");
                wb.SaveAs(@"c:\test.xlsx", Excel.XlFileFormat.xlOpenDocumentSpreadsheet);
                //wb.SaveCopyAs(@"c:\test.xlsx");
                wb.Close();
            }
            catch (Exception ex)
            {
                //_logger.Error(ex);
            }
            finally
            {
                app.Quit();
            }

`

无论我选择哪种文件格式,甚至没有提及该文件格式,我总是在 SaveAs 上遇到上述异常..

有什么想法吗?

【问题讨论】:

  • 我尝试使用下面的代码使用 OpenXML 库打开 html。但它给出了输入流代码var doc = SpreadsheetDocument.Open(resultsHTML.ToString(), false); 中的无效字符的错误,其中resultsHTML 是带有HTML 的StringWriter 对象
  • 在黑暗中拍摄:尝试不同的文件夹。由于宏安全设置,Office 应用程序有时会出现与根 C:\ 相关的权限问题。如果可以的话,试试桌面。
  • 感谢您的提示。除了\之外,我也尝试了不同的本地文件夹,但仍然出现相同的异常。
  • 当然,如果您通过在 Excel 中打开 .html 并执行 SaveAs to Excel 工作簿手动执行相同的操作,它确实可以正常工作。
  • 如果只打开一个空白工作簿并保存空白工作簿,它会起作用吗?这将确定问题是保存过程还是文件内容。

标签: c# html xml excel xslt


【解决方案1】:

这是更新后的代码,它以 bytes[] html 作为输入并以 bytes[] 为单位返回 xlsx

public static byte[] DoConvertXlDataToOpenXml(byte[] data, FileInfo fileInfo)
        {
            ExcelInterop.Application excelApp = null;
            ExcelInterop.Workbooks workBooks = null;
            ExcelInterop.Workbook workBook = null;
            FileInfo tempFile = null;
            FileInfo convertedTempFile = null;

            try
            {
                //Stream the file to temporary location, overwrite if exists
                tempFile = new FileInfo(Path.ChangeExtension(Path.Combine(Path.GetTempFileName()), fileInfo.Extension));

                using (var destStream = new FileStream(tempFile.FullName, FileMode.Create, FileAccess.Write))
                {
                    destStream.Write(data, 0, data.Length);
                }

                //open original
                excelApp = new ExcelInterop.Application();
                excelApp.Visible = false;
                excelApp.DisplayAlerts = false;

                workBooks = excelApp.Workbooks;

                workBook = workBooks.Open(tempFile.FullName);

                convertedTempFile = new FileInfo(Path.ChangeExtension(Path.GetTempFileName(), "XLSX"));

                //Save as XLSX
                excelApp.Application.ActiveWorkbook.SaveAs(
                     convertedTempFile.FullName
                     , Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook
                     , ConflictResolution: ExcelInterop.XlSaveConflictResolution.xlLocalSessionChanges);

                excelApp.Application.ActiveWorkbook.Close();

                return File.ReadAllBytes(convertedTempFile.FullName);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (workBooks != null)
                    Marshal.ReleaseComObject(workBooks);

                if (workBook != null)
                    Marshal.ReleaseComObject(workBook);

                if (excelApp != null)
                    Marshal.ReleaseComObject(excelApp);

                if (tempFile != null && tempFile.Exists)
                    tempFile.Delete();

                if (convertedTempFile != null && convertedTempFile.Exists)
                {
                    convertedTempFile.Delete();
                }
            }
        }

【讨论】:

    【解决方案2】:

    此代码有效。事实证明,我得到的异常仅与我试图保存的文件格式有关。当我将其更改为 Open XML 工作簿时,它保存得很好。

    using Excel = Microsoft.Office.Interop.Excel;
    .
    .
    .
    
    var app = new Excel.Application();
    
        Excel.Workbook wb = null;
    
                            try
                            {
                                wb = app.Workbooks.Open(@"c:\test.html");
                                wb.SaveAs(@"c:\test.xlsx", Excel.XlFileFormat.xlOpenXMLWorkbook);
                                //wb.SaveCopyAs(@"c:\test.xlsx");
                                wb.Close();
                            }
                            catch (Exception ex)
                            {
                                //_logger.Error(ex);
                            }
                            finally
                            {
                                app.Quit();
                            }
    

    【讨论】:

    • 澄清一下,没有办法将 html 文件从 MemoryStream 保存到 xslx 文件中。您可以执行 Excel Interop 的 SaveAs 方法将 html 文件保存到 xlsx 中,但这需要您将 Memorystream 转储到 html 文件中,然后执行 SaveAs。或者,您可以使用带有 Excel 输出目标的 xslt 样式表将 XML 直接转换为 Excel 文件 (xlsx)。
    最近更新 更多