Экспорт больших данных в excel в asp.net c#

Я пытаюсь экспортировать один набор данных в файл Excel. набор данных содержит более 20 таблиц данных (каждая таблица будет отображаться как отдельный лист в окончательном выходном файле Excel), и каждая таблица содержит более 30 + k строк, около 10 столбцов. Я читаю эти данные из другого ресурса и сохраняю их в наборе данных. не использовать никакую базу данных для его хранения. Я использую Open XML и Closed XML от здесь для выполнения этого процесса. он работает нормально до 15-20 таблиц данных, но более 25 занимает слишком много времени. Мы будем очень благодарны за любые предложения или помощь.

Образец кода:

 using (XLWorkbook wb = new XLWorkbook())
 {
   foreach (DataTable dt in dsData.Tables)
   {
     wb.Worksheets.Add(dt);
   }
   Response.Clear();
   Response.Buffer = true;
   Response.Charset = "";
   Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
   Response.AddHeader("content-disposition", "attachment;filename=DataSet.xlsx");
   wb.SaveAs(Response.OutputStream);
   Response.Flush();
   Response.End();   
 }

Дайте определение «Занимает слишком много времени». Сколько времени занимает проблема, когда вы открываете файл или скачиваете файл?

Goodbye StackExchange 10.09.2018 09:40

Почему вы сохраняете в MemoryStream, а затем сразу копируете его в OutputStream? Есть ли причина, по которой вы просто не сохраняете в OutputStream?

Llama 10.09.2018 09:41

Обычно я бы никогда не пытался сохранить всю базу данных, чтобы преуспеть. Во-первых, базы данных могут содержать намного больше данных, чем может обработать Excel. По какой причине вы сохраняете базу данных в Excel?

martijn 10.09.2018 09:46

@FrankerZ на добавление таблицы данных в объект XLWorkbook уходит более 20 минут.

Jzl 10.09.2018 09:46

@John Я тоже пробовал, поток памяти не обязателен

Jzl 10.09.2018 09:48

@martijn Я ничего не сохраняю в базе данных. Я читаю из одного источника (это другой формат файла и разные файлы) и записываю окончательный результат в один файл excel

Jzl 10.09.2018 09:49

Вполне возможно, что набор данных настолько велик, что вызывает проблемы в системе управления памятью. Это может сработать, если разрезать работу на более мелкие части, например, чтение и сохранение одной таблицы данных за раз.

martijn 10.09.2018 10:12

@martijn разделение не является правильным или невозможно здесь

Jzl 10.09.2018 10:58

почему вы хотите выгрузить такой огромный набор данных в Excel? Нет лучшего способа с этим работать?

ADyson 10.09.2018 11:11

@Jzl: вы хотите сказать, что вы не можете открыть datatable отдельно? надо их все сразу открывать?

martijn 10.09.2018 11:47

@ADyson, мои данные такие. тогда да, я тоже ищу другие пути

Jzl 10.09.2018 11:55

«мои данные такие». Я не понимаю твоей точки зрения. Зачем он нужен именно в Excel?

ADyson 10.09.2018 11:57

@martijn У меня есть набор данных и разные таблицы данных. Я просто хочу экспортировать его в разные листы Excel. пожалуйста, посоветуйте мне, есть ли другой способ добиться этого

Jzl 10.09.2018 11:57

@Jzl - мой ответ здесь может помочь в этом. Это чистый подход OpenXml - stackoverflow.com/questions/32690851/…

petelids 26.09.2018 13:42
0
14
4 713
1

Ответы 1

После некоторых исследований я нашел решение для этого, я протестировал приведенный ниже код с более чем 1 миллионом данных и его исправность. Может быть, кому-нибудь это будет полезно. Я удалил ссылку closedxml и добавил ссылку Interop.Microsoft.Office.Core.dll. затем я написал следующий код.

Требуемое пространство имен: используя Excel = Microsoft.Office.Interop.Excel, используя System.Runtime.InteropServices

    Excel.Workbook xlWorkBook;
    Excel.Application xlApp;
    Excel.Worksheet xlWorkSheet;
    Excel.Range Startrange;
    Excel.Range HeaderStartrange;
    public bool StartExport(DataTable dtbl, bool isFirst, bool isLast, string strOutputPath, string TemplateLocation, string TemplateFullName, int SectionOrder, int totalNoOfSheets)
    {
        bool isSuccess = false;
        try
        {
            if (isFirst)
            {
                CopyTemplate(TemplateLocation, strOutputPath, TemplateFullName);
                xlApp = new Excel.Application();
                if (xlApp == null)
                {
                    throw new Exception("Excel is not properly installed!!");
                }
                xlWorkBook = xlApp.Workbooks.Open(@strOutputPath + TemplateFullName, 0, false, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);

                // To Add Sheets Dynamically
                for (int i = 0; i <= totalNoOfSheets; i++)
                {
                    int count = xlWorkBook.Worksheets.Count;
                    Excel.Worksheet addedSheet = xlWorkBook.Worksheets.Add(Type.Missing,
                            xlWorkBook.Worksheets[count], Type.Missing, Type.Missing);
                    addedSheet.Name = "Sheet " + i.ToString();
                }
            }
            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(SectionOrder);
            Startrange = xlWorkSheet.get_Range("A2");
            HeaderStartrange = xlWorkSheet.get_Range("A1");
            FillInExcel(Startrange, HeaderStartrange, dtbl);
            xlWorkSheet.Name = dtbl.TableName;
            if (isLast)
            {
                xlApp.DisplayAlerts = false;
                xlWorkBook.SaveAs(@strOutputPath + TemplateFullName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing,
                    Type.Missing, Type.Missing);
                xlWorkBook.Close(true, null, null);
                xlApp.Quit();
                Marshal.ReleaseComObject(xlWorkSheet);
                Marshal.ReleaseComObject(xlWorkBook);
                Marshal.ReleaseComObject(xlApp);
                GC.WaitForPendingFinalizers();
                GC.Collect();
                isSuccess = true;
            }
        }
        catch (Exception ex)
        {
            isSuccess = false;
            throw;
        }
        return isSuccess;
    }

    private void FillInExcel(Excel.Range startrange, Excel.Range HeaderStartRange, DataTable dtblData)
    {
        int rw = 0;
        int cl = 0;
        try
        {
            // Fill The Report Content Data Here
            rw = dtblData.Rows.Count;
            cl = dtblData.Columns.Count;
            string[,] data = new string[rw, cl];
            // Adding Columns Here
            for (var row = 1; row <= rw; row++)
            {
                for (var column = 1; column <= cl; column++)
                {
                    data[row - 1, column - 1] = dtblData.Rows[row - 1][column - 1].ToString();
                }
            }
            Excel.Range endRange = (Excel.Range)xlWorkSheet.Cells[rw + (startrange.Cells.Row - 1), cl + (startrange.Cells.Column - 1)];
            Excel.Range writeRange = xlWorkSheet.Range[startrange, endRange];
            writeRange.Value2 = data;
            writeRange.Formula = writeRange.Formula;
            data = null;
            startrange = null;
            endRange = null;
            writeRange = null;
        }

        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }

Я вызвал эту функцию startExport выше для каждого цикла с необходимыми параметрами, такими как (данные, первый или последний лист, путь вывода, имя шаблона, порядок разделов и общее количество требуемых листов)

CopyTemplate не существует

Victor 25.06.2019 12:56

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