ajitsit07 Ответов: 1

Нужен ваш опыт-чтобы оптимизировать код и ускорить загрузку excel.


Всем Привет,

Я разработал инструмент отчетности, в котором я вставляю строки в excel (имея те же столбцы no., что и в Macro enable excel sheet).

Этот фрагмент кода работает совершенно нормально и загружается в excel в приличное время. Но мне нужна ваша помощь, чтобы улучшить и оптимизировать скорость загрузки.

Спасибо за ваш совет и время.

Что я уже пробовал:

Вот строки кода: класс под App_code.

public static bool fillExcelFile(string filePath, DataSet dataSet, string sheetName, string tempSheetName)
    {
        DataTable oledbdatatbl = null;
        using (OleDbDataAdapter oledbadap = new OleDbDataAdapter(string.Format("SELECT * FROM [{0}$]", sheetName),
                  string.Format(@"Data Source={0};Provider=Microsoft.ACE.OLEDB.12.0; Extended Properties=Excel 12.0;", filePath)))
        {
            try
            {
                oledbdatatbl = new System.Data.DataTable("ReportTable");
                oledbadap.Fill(oledbdatatbl);
            }
            catch (Exception ex)
            {
              //  Error_SendMail(ex);
                return false;
            }
        }

        System.Text.StringBuilder sbColumns = new System.Text.StringBuilder();
        int coloumsCount = 0;
        for (int icol = 0; icol < (oledbdatatbl.Columns.Count); icol++)
        {
            coloumsCount++;
            sbColumns.Append(string.Format(",[{0}]", oledbdatatbl.Columns[icol].ColumnName));
        }

        if (sbColumns.Length > 0)
            sbColumns.Remove(0, 1);

        using (OleDbConnection oledbConn = new OleDbConnection(string.Format(@"Data Source={0};Provider=Microsoft.ACE.OLEDB.12.0; Extended Properties=Excel 12.0;", filePath)))
        {
            using (OleDbCommand oledbCmd = new OleDbCommand())
            {
                System.Text.StringBuilder sbValues = new System.Text.StringBuilder();
                int valuesCount = 0;

                for (int irow = 0; irow < dataSet.Tables[0].Rows.Count; irow++)
                {
                    if (sbValues.Length > 0)
                        sbValues.Remove(0, sbValues.Length);
                    try
                    {
                        valuesCount = 0;
                        for (int idatacol = 0; idatacol < dataSet.Tables[0].Columns.Count; idatacol++)
                        {
                            valuesCount++;

                            sbValues.Append(string.Format(",'{0}'", Convert.ToString(dataSet.Tables[0].Rows[irow][idatacol]).Contains("'") ?
                                Convert.ToString(dataSet.Tables[0].Rows[irow][idatacol]).Replace("'", "''") :
                                Convert.ToString(dataSet.Tables[0].Rows[irow][idatacol])));
                        }

                        if (sbValues.Length > 0)
                            sbValues.Remove(0, 1);
                    }
                    catch (Exception ex)
                    {
                      //  Error_SendMail(ex);
                        continue;
                    }

                    if (coloumsCount == valuesCount)
                    {
                        try
                        {
                            oledbCmd.CommandText = string.Format("insert into [{0}$]({1})values({2})", tempSheetName, sbColumns.ToString(), sbValues.ToString());
                            oledbCmd.CommandType = System.Data.CommandType.Text;
                            // oledbCmd.CommandTimeout = 200;

                            if (oledbConn.State == System.Data.ConnectionState.Closed)
                            {
                                oledbConn.Open();
                                oledbCmd.Connection = oledbConn;
                            }
                            oledbCmd.ExecuteNonQuery();
                            // oledbConn.Close();


                        }
                        catch (Exception ex)
                        {

                            if (oledbConn.State == System.Data.ConnectionState.Open)
                                oledbConn.Close();
                            //  Error_SendMail(ex);
                        }
                        finally
                        { 
                        
                        }
                    }
                }

                if (oledbConn.State == System.Data.ConnectionState.Open)
                    oledbConn.Close();
            }
        }
        return true;
    }

Richard MacCutchan

Где происходит загрузка и в чем проблема?

ajitsit07

В коде нет никаких проблем, я должен улучшить скорость. так что excel будет загружен за меньшее время. Например, теперь это займет 40 секунд, и я хочу сократить его время до 20 секунд.

Эта загрузка excel находится в разделе C#. ASP.net сайт под меню.

публичный статический тип fillExcelFile(строку путь к файлу, набор данных, набор данных, строки, листа, строки tempSheetName)

Здесь: Путь_к_файлу - это сервер, подключенный путь файла (макроса включить файл Excel) доступны на сервере.
Набор данных: содержит данные, которые необходимо вставить во временный лист excel.



Вам тоже нужна какая-нибудь другая информация?

Richard MacCutchan

Скорость загрузки зависит от сетевых соединений между сервером и клиентом.

ajitsit07

Спасибо, Ричард.

Да, я согласен с вами. Но оптимизированный код имеет значение.
Есть ли какие-либо возможности для оптимизации приведенного выше кода?

Dave Kreskowiak

Вы объединяетесь с различными операциями в своем вопросе. Вам нужна либо помощь в создании листа Excel и ускорении его работы, либо помощь в операции загрузки.

Так что же это? Одно не имеет ничего общего с другим.

Richard MacCutchan

Каким образом оптимизировать? И, как уже отметил Дэйв,этот код не имеет ничего общего с загрузкой.

ajitsit07

Здесь sbColumns содержат все имя, которое есть в excel, а sbValues содержат все значение. мы вставляем ИТ-строку за строкой В временный лист excel. Во время отладки 'oledbCmd.ExecuteNonQuery (); ' строка занимает время.

oledbCmd.CommandText = строка.Формат ("вставить в [{0}$]({1})values ({2})", tempSheetName, sbColumns.ToString (), sbValues.Метод toString());
oledbCmd.Свойство Commandtype = Система.Данных.Свойство commandtype.Текст;
// oledbCmd.CommandTimeout = 200;

если (oledbConn.Государство = Система.Данных.Состояние соединения.Закрытый)
{
oledbConn.Открыть();
oledbCmd.Соединение = oledbConn;
}
oledbCmd.Метод executenonquery();

Richard MacCutchan

Время, затраченное на выполнение команды, зависит от объема обрабатываемых данных. Я не вижу ничего, что можно было бы изменить, если только вы не используете взаимодействие Excel вместо OLE.

Nathan Minier

Вы используете Ole-провайдер, это займет больше времени, так как он должен пройти через эти преобразования ADO, прежде чем быть записанным в формат Excel.

Есть 2 способа ускорить это: использовать DocumentFormat.Пространство имен OpenXML или создайте файл. csv на заказ. И то, и другое существенно отличалось бы от того, что вы имеете сейчас.

ajitsit07

Мне нужно, чтобы пользовательский макрос включил excel, поэтому я не могу использовать файл .csv.
Есть ли какие-либо возможности для оптимизации приведенного выше кода?

1 Ответов

Рейтинг:
2

Sreekanth Mothukuru

Попробуйте сжать файл, прежде чем позволить пользователю загрузить его. Используйте код c# для сжатия файла в формат zip/7z.

Таким образом, вы можете оптимизировать скорость загрузки.


ajitsit07

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