【问题标题】:OpenXML - Create and Open Excel File without saving ItOpenXML - 创建和打开 Excel 文件而不保存它
【发布时间】:2019-04-08 07:59:15
【问题描述】:

我有一个代码,它使用 OpenXML 从 Datatable 创建一个新的 Excel 文件。完成创建此文件后,我想为用户打开它但不保存它。基本上,Excel 在这种情况下所做的是将 excel 文件打开为“Workbook1”,然后如果您希望手动保存它。我有这个需求是因为用户想在将文件保存到磁盘之前检查数据是否对应。

这可以通过 Visibility 属性在 Interop 中完成(我已经有了这个解决方案,但问题是 Interop 在处理大量数据时非常慢,所以用户对它不满意),但我找不到办法在 OpenXML 中也是如此。如果有人有任何建议,请告诉我。这是我创建 Excel 文件的代码:

  public void Export_To_Excel_stream(MemoryStream ms, DataTable dt)
        {
            using (SpreadsheetDocument dokument = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook))
            {
                WorkbookPart workbookPart = dokument.AddWorkbookPart();
                workbookPart.Workbook = new Workbook();

                WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                var sheetData = new SheetData();
                worksheetPart.Worksheet = new Worksheet(sheetData);

                Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
                Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = dt.TableName };
                sheets.Append(sheet);

                //header row
                Row header = new Row();
                List<String> Cols = new List<string>();
                foreach (DataColumn col in dt.Columns)
                {
                    Cols.Add(col.ColumnName);

                    Cell cell = new Cell
                    {
                        DataType = CellValues.String,
                        CellValue = new CellValue(col.ColumnName)
                    };
                    header.AppendChild(cell);
                }
                sheetData.AppendChild(header);


                foreach (DataRow row in dt.Rows)
                {
                    Row new_row = new Row();
                    foreach (String col in Cols)
                    {
                        Cell cell = new Cell
                        {
                            DataType = CellValues.String,
                            CellValue = new CellValue(row[col].ToString())
                        };
                        new_row.AppendChild(cell);
                    }
                    sheetData.AppendChild(new_row);
                }
                workbookPart.Workbook.Save();

            }

【问题讨论】:

  • 要么是直接文件操作,要么是全速,而是创建一个文件。或者没有文件的缓慢互操作。
  • 也许您仍然可以使用直接文件操作,但在它之上做一些事情来模拟您想要的?不确定,但请检查您是否可以重置保存的标志或复制文件,或者在内存中打开它(从流等)。
  • @Sinatr,谢谢你的回答,至少现在我知道我在哪里......但我不确定我能在它之上做什么来模拟,你在想什么?
  • 例如检查this question。您创建文件并像以前一样保存它,然后在MemoryStream 中打开它,最后在 excel 中打开它。这将可能导致文件被按你想要的方式打开:Workbook1 名称和 usaved 标志。也许您可以使用 OpenXml 从流中打开,调查这种可能性。
  • 另一个值得检查的想法是您是否可以复制工作区。有一个 excel 实例加载文件(不向用户显示这个?)并将工作区复制到一个新实例中。或者可能只是打开工作区,然后复制(使用 VBS 脚本?)并关闭前一个(并删除文件)。

标签: c# openxml


【解决方案1】:

我发现最好的办法是将 Excel 文件作为进程打开,然后在进程结束时将其删除。但是,我的 OpenXML 代码是一个 .dll,所以当我关闭已打开 Excel 文件的应用程序时,它不会再自动删除:

public string file_path;

public void Export_To_Excel_stream(MemoryStream ms, DataTable dt)
{
    //...at the end, whe OPENXML file is created..        
    var open_Excel = Process.Start(file_path);
    open_Excel.EnableRaisingEvents = true;
    open_Excel.Exited += new EventHandler(open_excel_Exited);
 }

public void open_excel_Exited(object sender, EventArgs e)
{
     File.Delete(file_path);
}

如果有人有更好的解决方案,我会非常高兴:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多