OpenXML — создание и открытие файла Excel без его сохранения

У меня есть код, который создает новый файл Excel из Datatable, используя OpenXML. Когда я закончу создание этого файла, я хочу открыть его для пользователя, но не сохраняя его. В основном, что делает Excel в этом случае, так это то, что он открывает файл Excel как «Workbook1», а затем, если вы хотите, сохраняете его вручную. У меня есть это требование, потому что пользователи хотят проверить соответствие данных перед сохранением файла на диск.

Это можно сделать в свойстве Interop by Visibility (у меня уже есть это решение, но проблема в том, что 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 08.04.2019 10:10

Возможно, вы все еще могли бы использовать прямое манипулирование файлами, но сделать что-то сверх этого, чтобы имитировать то, что вы хотите? Не уверен, но проверьте, можете ли вы сбросить сохраненный флаг или, возможно, скопировать файл, или, может быть, открыть его в памяти (из потока и т. д.).

Sinatr 08.04.2019 10:13

@Sinatr, спасибо за ответ, по крайней мере, теперь я знаю, где я нахожусь ... Но я не уверен, что я мог бы сделать поверх этого, чтобы смоделировать, о чем ты думаешь?

Lucy82 08.04.2019 10:17

Например. проверьте этот вопрос. Вы создаете файл и сохраняете его, как уже делали, затем открываете его в MemoryStream и, наконец, открываете в Excel. Это приведет к тому, что наверное приведет к тому, что файл будет открыт так, как вы хотите: с именем Workbook1 и флагом использования. Возможно, вы можете открыть из потока с помощью OpenXml, изучите эту возможность.

Sinatr 08.04.2019 10:28

Еще одна идея, которую стоит проверить, — это возможность копирования рабочей области. Имейте один файл загрузки экземпляра Excel (не показывайте его пользователю?) И скопируйте рабочее пространство в новый экземпляр. Или, может быть, просто открыть рабочее пространство, затем скопировать (используя скрипты VBS?) и закрыть предыдущее (и удалить файл).

Sinatr 08.04.2019 10:38

@Sinatr, все эти предложения намного выше моих знаний. Возможно, вы могли бы опубликовать пример кода, чтобы дать мне подсказку.... Но в настоящее время я пытаюсь использовать Interop с кодом выше, я пытаюсь передать поток памяти в новый Interop.Excel.Application(), а затем просто открыть файл .

Lucy82 08.04.2019 10:44

Предназначен ли этот файл для отправки обратно пользователю через веб-интерфейс?

Taterhead 09.04.2019 09:45

@Taterhead, нет, это настольное приложение C#, экспорт в Excel происходит из элемента управления Datagridview. К сожалению, пользователи используют это довольно часто, поэтому им нужно решение, подобное предыдущему (Interop), без сохранения файла. Но их не устраивает скорость экспорта. Удар.

Lucy82 10.04.2019 06:52

это для запуска на обычном современном рабочем столе Windows 8 или 10? не в ситуации с VDI или тонким клиентом, правильно?

Taterhead 10.04.2019 15:16

@Taterhead, он предназначен только для Windows 7-10.

Lucy82 10.04.2019 15:19

Привет, Люси. Возможно, это повторяющийся вопрос. См.: stackoverflow.com/a/29950024/819019. Дайте мне знать, если это сработает, и мы сможем закрыть это как дубликат.

Taterhead 19.04.2019 15:02

@Taterhead, я уже видел этот ответ и пробовал, прежде чем публиковать здесь, но не смог заставить его работать. Однако этот ответ предназначен для веб-приложений.

Lucy82 20.04.2019 19:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
12
1 137
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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);
}

Я был бы более чем счастлив, если бы у кого-то было лучшее решение :)

Другие вопросы по теме