Introdução: Ao exportar dados para Excel, o processo estava apresentando lentidão significativa.
Código original:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IPC.Helper
{
class ExcelExportUtil
{
public static string expotExcel(List<DataTable> tabelasHistorico, string[] nomesTipos, string nomeArquivoSalvo)
{
try
{
Microsoft.Office.Interop.Excel.Application aplicacaoExcel = new Microsoft.Office.Interop.Excel.Application();
if (aplicacaoExcel == null)
{
return "Não foi possível criar objeto Excel. O Excel pode não estar instalado neste computador";
}
Microsoft.Office.Interop.Excel.Workbooks workbooks = aplicacaoExcel.Workbooks;
Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
Microsoft.Office.Interop.Excel.Worksheet worksheet3 = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];
Microsoft.Office.Interop.Excel.Worksheet worksheet2 = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.Add(Type.Missing,Type.Missing,Type.Missing,Type.Missing);
worksheet2.Name = nomesTipos[0];
// Escrevendo cabeçalho
int contadorTitulos = 1;
worksheet2.Cells[1, contadorTitulos++] = "Tempo 1";
worksheet2.Cells[1, contadorTitulos++] = "Valor Parâmetro";
worksheet2.Cells[1, contadorTitulos++] = "Valor Máximo";
worksheet2.Cells[1, contadorTitulos++] = "Valor Mínimo";
// Obtendo hora atual
DateTime agora = DateTime.Now;
string horaFormatada = agora.ToString("yyyy-MM-dd HH:mm:ss");
Console.WriteLine(horaFormatada);
// Escrevendo valores
for (int r = 0; r < tabelasHistorico[0].Rows.Count; r++)
{
int contadorLinhas = 1;
worksheet2.Cells[r + 2, contadorLinhas++] = " " + tabelasHistorico[0].Rows[r]["data_time"].ToString() + "\t";
worksheet2.Cells[r + 2, contadorLinhas++] = tabelasHistorico[0].Rows[r]["conc"].ToString();
worksheet2.Cells[r + 2, contadorLinhas++] = tabelasHistorico[0].Rows[r]["max"].ToString();
worksheet2.Cells[r + 2, contadorLinhas++] = tabelasHistorico[0].Rows[r]["min"].ToString();
System.Windows.Forms.Application.DoEvents();
}
// Obtendo hora atual novamente
DateTime agora1 = DateTime.Now;
string horaFormatada1 = agora1.ToString("yyyy-MM-dd HH:mm:ss");
Console.WriteLine(horaFormatada1);
worksheet2.Columns.EntireColumn.AutoFit(); // Ajuste automático de largura de colunas
workbook.Saved = true;
workbook.SaveCopyAs(nomeArquivoSalvo);
aplicacaoExcel.Quit();
GC.Collect(); // Forçando coleta de lixo
return "Exportação concluída com sucesso";
}
catch(Exception e)
{
return e.Message;
}
}
}
}
Ao adicionar registros de tempo ao código, descobriu-se que o loop de escrita estava levando cerca de 35 segundos para quase 3000 registros. Após otimização, o tempo foi reduzido para apenas 1 segundo.
Estratégias de otimização: 1. No loop for, mover o contador de tamanho para fora do loop, pois chamadas repetidas a .size() causam lentidão;
- Ao escrever no Excel, evitar a escrita célula por célula e usar escrita em renge (entervalo) em vez disso;
Parte de escrita de dados, código modificado:
object[,] cabecalho = worksheet2.Range["A1", "D1"].Value2;
cabecalho[1, 1] = "Tempo";
cabecalho[1, 2] = "Valor Parâmetro";
cabecalho[1, 3] = "Valor Máximo";
cabecalho[1, 4] = "Valor Mínimo";
worksheet2.Range["A1", "D1"].Value2 = cabecalho;
// Escrevendo valores
int totalLinhas = tabelasHistorico[0].Rows.Count;
string ultimoIntervalo = "D" + totalLinhas + 1;
object[,] dados = worksheet2.Range["A2", ultimoIntervalo].Value2;
for (int r = 0; r < totalLinhas; r++)
{
dados[r+1, 1] = " " + tabelasHistorico[0].Rows[r]["data_time"].ToString() + "\t";
dados[r+1, 2] = tabelasHistorico[0].Rows[r]["conc"].ToString();
dados[r + 1, 3] = tabelasHistorico[0].Rows[r]["max"].ToString();
dados[r + 1, 4] = tabelasHistorico[0].Rows[r]["min"].ToString();
System.Windows.Forms.Application.DoEvents();
}
worksheet2.Range["A2", ultimoIntervalo].Value2 = dados;