terça-feira, 15 de dezembro de 2015

C# classe para exportação em excel

using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Linq;

namespace TF.Util
{

    /// <summary>Classe para exportação em lote no MS Excel
    /// Essa classe foi construida com base no artigo: http://www.codeproject.com/KB/office/FastExcelExporting.aspx
    /// Teste de comparação com o método de exportação "linha a linha":
    /// Número de linhas exportadas: 452 x 25 colunas (com formatação em 7 colunas em ambas exportações, como exemplo abaixo)
    /// Tempo classe para exportação em lote:  2.115 segundos
    /// Tempo classe para exp. linha a linha: 29.708 segundos
    /// Número de linhas exportadas: 957 x 25 colunas (com formatação em 7 colunas em ambas exportações, como exemplo abaixo)
    /// Tempo classe para exportação em lote:  3.078 segundos
    /// Tempo classe para exp. linha a linha: 69.173 segundos
    /// Testado em computador com windows XP SP3 - MS Excel 2007
    /// Intel Pentium Dual 1,60 GHz - 2GB RAM
    /// </summary>
    /// <example>
    /// <code>
    /// List<Formatacao> iFormat = new List<Formatacao>();
    /// iFormat.Add(new Formatacao("H2", "MM/DD/YYYY"));
    /// iFormat.Add(new Formatacao("I2", "MM/DD/YYYY"));
    /// iFormat.Add(new Formatacao("M2", "MM/DD/YYYY"));
    /// iFormat.Add(new Formatacao("N2", "MM/DD/YYYY"));
    /// iFormat.Add(new Formatacao("L2", "###,###,#0.00"));
    /// iFormat.Add(new Formatacao("X2", "###,###,#0.00"));
    /// iFormat.Add(new Formatacao("Y2", "###,###,#0.00"));
    /// ExportExcel.ExportToExcel(demoDataSet, fastExportFilePath, iFormat);
    /// </code>
    /// </example>
    public static class ExportExcel
{
        public static Boolean _SalvarComo = true;

        public delegate void EventoContaRow(Int32 pValor, ProgressBar pPrg);
        public delegate void EventoTotalRow(Int32 pValor, ProgressBar pPrg);
        public static event EventoContaRow ProgressoRow;
        public static event EventoTotalRow TotalRow;

        public delegate void EventoContaCol(Int32 pValor, ProgressBar pPrg);
        public delegate void EventoTotalCol(String pPlanilha, Int32 pValor, System.Windows.Forms.Label pLbl, ProgressBar pPrg);
        public static event EventoContaCol ProgressoCol;
        public static event EventoTotalCol TotalCol;

        /// <summary>Função para exportação em lote no MS Excel sem formatações nos campos
        /// </summary>
        /// <param name="pDataSet">Objeto DataSet com os dados a serem escritos no arquivo, os nomes das colunas serão usados na primeira linha do excel como cabeçalho</param>
        /// <param name="pCamArquivo">Local e nome do arquivo</param>
        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo)
        {
            ExportToExcel(pDataSet, pCamArquivo, null);
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, null);
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao, List<Filtros> pFiltros)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, null, null, null);
        }

        /// <summary>
        /// A contagem começa em 1:
        /// 1-A
        /// 2-B
        /// 3-C
        /// 4-D
        /// etc
        /// </summary>
        /// <param name="pPosicao"></param>
        /// <returns></returns>
        //public static String Letraold(Int32 pPosicao)
        //{
        //    try
        //    {
        //        if (pPosicao > 26)
        //            pPosicao = pPosicao;

        //        if (pPosicao > 702)
        //            pPosicao = pPosicao;

        //        // Calculate the final column letter
        //        string finalColLetter = string.Empty;
        //        string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        //        int colCharsetLen = colCharset.Length;

        //        if (pPosicao > colCharsetLen)
        //        {
        //            finalColLetter += colCharset.Substring((pPosicao - 1) / colCharsetLen - 1, 1);
        //        }

        //        finalColLetter += colCharset.Substring((pPosicao - 1) % colCharsetLen, 1);

        //        return finalColLetter;
        //    }
        //    catch (Exception ex)
        //    {
             
        //        throw;
        //    }
        //}

        public static String Letra(Int32 pPosicao)
        {
            try
            {
                if (pPosicao < 27)
                    return Char.ConvertFromUtf32(64 + pPosicao);

                if (pPosicao < 703)
                    return Char.ConvertFromUtf32(64 + ((pPosicao - 1) / 26)) + Char.ConvertFromUtf32(65 + ((pPosicao - 1) % 26));

                if (pPosicao < 18279)
                    return Char.ConvertFromUtf32(65 + (((pPosicao-703) / 676) % 26))
                        + Char.ConvertFromUtf32(65 + ((pPosicao -27) / 26) % 26)
                        + Char.ConvertFromUtf32(65 + ((pPosicao -1) % 26));

                return "";
            }
            catch (Exception ex)
            {

                throw;
            }
        }

        public static void FormatarDataNumero(DataSet iDsGerar, List<Filtros> iFiltro, List<Formatacao> iFormat)
        {
            if (iFormat == null)
                iFormat = new List<Formatacao>();
            foreach (System.Data.DataTable dt in iDsGerar.Tables)
            {
                String iLinhaInicial;
                if (iFiltro != null)
                {
                    var result = iFiltro.Where(f => f.Planilha != null && f.Planilha.Trim().Equals(dt.TableName.Trim(), StringComparison.OrdinalIgnoreCase));
                    iLinhaInicial = (result.Count() + 2).ToString();
                }
                else
                    iLinhaInicial = "2";
                foreach (DataColumn iDc in dt.Columns)
                {
                    if (iDc.DataType.Name.Trim().Equals("DateTime", StringComparison.OrdinalIgnoreCase)
                        || (iDc.DataType.Name.Trim().Equals("Double", StringComparison.OrdinalIgnoreCase)
                        || iDc.DataType.Name.Trim().Equals("Decimal", StringComparison.OrdinalIgnoreCase)))
                    {
                        if (iDc.ExtendedProperties.Contains("Formato"))
                        {
                            iFormat.Add(new Formatacao(dt.TableName, ExportExcel.Letra(iDc.Ordinal + 1) + iLinhaInicial, iDc.ExtendedProperties["Formato"].ToString()));
                        }
                        else
                        {
                            if (iDc.DataType.Name.Trim().Equals("DateTime", StringComparison.OrdinalIgnoreCase))
                                iFormat.Add(new Formatacao(dt.TableName, ExportExcel.Letra(iDc.Ordinal + 1) + iLinhaInicial, Geral._FormatoData));
                            else if (iDc.DataType.Name.Trim().Equals("Double", StringComparison.OrdinalIgnoreCase)
                                    || iDc.DataType.Name.Trim().Equals("Decimal", StringComparison.OrdinalIgnoreCase))
                                iFormat.Add(new Formatacao(dt.TableName, ExportExcel.Letra(iDc.Ordinal + 1) + iLinhaInicial, Geral._FormatoMoeda));
                        }
                    }
                }
            }
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao,
            List<Filtros> pFiltros, ProgressBar pPrgRow, System.Windows.Forms.Label pLblCol, ProgressBar pPrgCol)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, pPrgRow, pLblCol, pPrgCol, false);
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao,
            List<Filtros> pFiltros, ProgressBar pPrgRow, System.Windows.Forms.Label pLblCol, ProgressBar pPrgCol, Boolean pAdicionarFiltro)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, pPrgRow, pLblCol, pPrgCol, pAdicionarFiltro, false, 0, true, false, string.Empty, string.Empty, Dados.VerVersaoExcel());
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao, List<Filtros> pFiltros, Boolean pAdicionarFiltro)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, null, null, null, pAdicionarFiltro, false, 0, true, false, string.Empty, string.Empty, Dados.VerVersaoExcel());
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao, List<Filtros> pFiltros,
            ProgressBar pPrgRow, System.Windows.Forms.Label pLblCol, ProgressBar pPrgCol,
            Boolean pAdicionarFiltro, Boolean pCongelar, Int32 pZoom)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, pPrgRow, pLblCol, pPrgCol, pAdicionarFiltro, pCongelar, pZoom, true, false, string.Empty, string.Empty, Dados.VerVersaoExcel());
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao, List<Filtros> pFiltros, Boolean pAdicionarFiltro,
            Boolean pCongelar, Int32 pZoom)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, null, null, null, pAdicionarFiltro, pCongelar, pZoom, true, false, string.Empty, string.Empty, Dados.VerVersaoExcel());
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao, List<Filtros> pFiltros, Boolean pAdicionarFiltro,
            Boolean pCongelar, Int32 pZoom, Boolean pDisplayGridlines, Boolean pBordas, String pFonte, String pAlinhamento)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, null, null, null, pAdicionarFiltro, pCongelar, pZoom, pDisplayGridlines, pBordas, pFonte, pAlinhamento, Dados.VerVersaoExcel());
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao,
            List<Filtros> pFiltros, ProgressBar pPrgRow, System.Windows.Forms.Label pLblCol, ProgressBar pPrgCol, Boolean pAdicionarFiltro,
            Boolean pCongelar, Int32 pZoom, Boolean pDisplayGridlines, Boolean pBordas, String pFonte, String pAlinhamento, Int32 pVersao)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, pPrgRow, pLblCol, pPrgCol, pAdicionarFiltro, pCongelar, pZoom, pDisplayGridlines,
                pBordas, pFonte, pAlinhamento, pVersao, null, null, null);
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao,
            List<Filtros> pFiltros, ProgressBar pPrgRow, System.Windows.Forms.Label pLblCol, ProgressBar pPrgCol, Boolean pAdicionarFiltro,
            Boolean pCongelar, Int32 pZoom, Boolean pDisplayGridlines, Boolean pBordas, String pFonte, String pAlinhamento, String pVAlign, String pHAlign)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, pPrgRow, pLblCol, pPrgCol, pAdicionarFiltro, pCongelar, pZoom, pDisplayGridlines,
                pBordas, pFonte, pAlinhamento, Dados.VerVersaoExcel(), null, null, null);
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao,
            List<Filtros> pFiltros, ProgressBar pPrgRow, System.Windows.Forms.Label pLblCol, ProgressBar pPrgCol, Boolean pAdicionarFiltro,
            Boolean pCongelar, Int32 pZoom, Boolean pDisplayGridlines, Boolean pBordas, String pFonte, String pAlinhamento, Int32 pVersao,
            List<DestacarCelulas> pCelulas, List<ColunasWrap> _ColunasWrap)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, pPrgRow, pLblCol, pPrgCol, pAdicionarFiltro, pCongelar, pZoom, pDisplayGridlines,
                pBordas, pFonte, pAlinhamento, pVersao, null, null, pCelulas, _ColunasWrap);
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao,
            List<Filtros> pFiltros, ProgressBar pPrgRow, System.Windows.Forms.Label pLblCol, ProgressBar pPrgCol, Boolean pAdicionarFiltro,
            Boolean pCongelar, Int32 pZoom, Boolean pDisplayGridlines, Boolean pBordas, String pFonte, String pAlinhamento, Int32 pVersao,
            List<DestacarCelulas> pCelulas)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao, pFiltros, pPrgRow, pLblCol, pPrgCol, pAdicionarFiltro, pCongelar, pZoom, pDisplayGridlines,
                pBordas, pFonte, pAlinhamento, pVersao, null, null, pCelulas);
        }

        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao,
            List<Filtros> pFiltros, ProgressBar pPrgRow, System.Windows.Forms.Label pLblCol, ProgressBar pPrgCol, Boolean pAdicionarFiltro,
            Boolean pCongelar, Int32 pZoom, Boolean pDisplayGridlines, Boolean pBordas, String pFonte, String pAlinhamento, Int32 pVersao,
            String pVAlign, String pHAlign, List<DestacarCelulas> pCelulas)
        {
            ExportToExcel(pDataSet, pCamArquivo, pFormatacao,
                pFiltros, pPrgRow, pLblCol, pPrgCol, pAdicionarFiltro,
                pCongelar, pZoom, pDisplayGridlines, pBordas, pFonte, pAlinhamento, pVersao,
                pVAlign, pHAlign, pCelulas, null);
        }

        public static String ExtensaoExcel(Int32 pVersaoExc)
        {
            if (pVersaoExc <= 0)
                pVersaoExc = Dados.VerVersaoExcel();
            String iExt = "xls";
            iExt += (pVersaoExc >= 12 ? "x" : "");
            return iExt;
        }

        public static String ExtensaoExcel()
        {
            return ExtensaoExcel(0);
        }

        public static String VerificarLinhasColunas(DataSet pDataSet)
        {
            return VerificarLinhasColunas(pDataSet, 0);
        }

        public static String VerificarLinhasColunas(DataSet pDataSet, Int32 pVersao)
        {
            if (pVersao <= 0)
                pVersao = Dados.VerVersaoExcel();

            Int32 iQtdMaxCol = 256;
            Int32 iQtdMaxLin = 65536;
            if (pVersao >= 12)
            {
                iQtdMaxCol = 16384;
                iQtdMaxLin = 1048576;
            }
            foreach (System.Data.DataTable iDtPlan in pDataSet.Tables)
            {
                if (iDtPlan.Columns.Count > iQtdMaxCol)
                    return ("Erro: DataTable com mais de " + iQtdMaxCol + " colunas (máximo permitido excel versão " + pVersao + ")");
                if (iDtPlan.Rows.Count > iQtdMaxLin)
                    return ("Erro: DataTable com mais de " + iQtdMaxLin + " linhas (máximo permitido excel versão " + pVersao + ")");
            }
            return string.Empty;
        }

        /// <summary>Função para exportação em lote no MS Excel, com possibilidade de formatação nos campos
        /// </summary>
        /// <param name="pDataSet">Objeto DataSet com os dados a serem escritos no arquivo, os nomes das colunas serão usados na primeira linha do excel como cabeçalho</param>
        /// <param name="pCamArquivo">Local e nome do arquivo</param>
        /// <param name="pFormatacao">Objeto com as formatações para as células, caso não tiver passar null</param>
        public static void ExportToExcel(DataSet pDataSet, string pCamArquivo, List<Formatacao> pFormatacao,
            List<Filtros> pFiltros, ProgressBar pPrgRow, System.Windows.Forms.Label pLblCol, ProgressBar pPrgCol, Boolean pAdicionarFiltro,
            Boolean pCongelar, Int32 pZoom, Boolean pDisplayGridlines, Boolean pBordas, String pFonte, String pAlinhamento, Int32 pVersao,
            String pVAlign, String pHAlign, List<DestacarCelulas> pCelulas, List<ColunasWrap> _ColunasWrap)
        {
            if (pDataSet == null)
                throw new Exception("Erro: Dataset vazio");

            if (pDataSet.Tables.Count < 1)
                throw new Exception("Erro: DataSet sem tabelas");

            if (pVersao == 0)
                pVersao = Dados.VerVersaoExcel();

            String iTxtVerColLin = VerificarLinhasColunas(pDataSet, pVersao);
            if (!Validacao.IsEmpty(iTxtVerColLin))
                throw new Exception(iTxtVerColLin);

            // Create the Excel Application object
            ApplicationClass excelApp = new ApplicationClass();

            //isso para evitar o problema de globalização causado pelo framework em PT ou US quando envia para o excel
            System.Globalization.CultureInfo cultura = new System.Globalization.CultureInfo("en-US");
            System.Threading.Thread.CurrentThread.CurrentCulture = cultura;

            // Create a new Excel Workbook
            Workbook excelWorkbook = excelApp.Workbooks.Add(Type.Missing);
            //Workbook excelWorkbook = excelApp.Workbooks.Open(@"C:\Documents and Settings\trust2\Meus documentos\Temp\aTeste_.xls");

            Int32 iMaxLong;
            if (pVersao >= 12)
                iMaxLong = 8203; //excel 2007 é limitado em 8203 caracteres
            else
                iMaxLong = 910; //o excel 2003 só aguenta até 910 https://social.msdn.microsoft.com/Forums/en-US/f09cf55a-1af5-46b3-9438-b818082144b0/910-characters-limited-when-export-data-to-excel-cell?forum=vbinterop

            Microsoft.Office.Interop.Excel.Range iRange = null;

            try
            {

                String iLetraDoInicio = "A";

                //iLetraDoInicio = "BW";

                //excelWorkbook = (Workbook)excelApp.GetType().InvokeMember("Workbooks", System.Reflection.BindingFlags.GetProperty, null, excelApp, null, new System.Globalization.CultureInfo(1033));          

                //excelApp.Application.WindowState = XlWindowState.xlMinimized;
                //excelApp.Application.Interactive = false; //meaning the user is not supposed to to change anything on Excel while your program is doing the work.
                excelApp.DisplayAlerts = false;
                excelApp.AlertBeforeOverwriting = false;
                // 27/07/2012 comentado para teste versao 11 - 2003
                //excelApp.EnableLargeOperationAlert = false; //não existe na versão 2003, foi adicionada na versão 2007

                int sheetIndex = 0;

                #region formatação automatica para datas
                if (pFormatacao == null || pFormatacao.Count == 0)
                {
                    pFormatacao = new List<Formatacao>();                  
                    FormatarDataNumero(pDataSet, pFiltros, pFormatacao);

                    //foreach (System.Data.DataTable dt in pDataSet.Tables)
                    //{
                    //    String iLinhaInicial;
                    //    if (pFiltros != null)
                    //    {
                    //        var result = pFiltros.Where(f => f.Planilha.Trim().Equals(dt.TableName.Trim(), StringComparison.OrdinalIgnoreCase));
                    //        iLinhaInicial = (result.Count() + 2).ToString();
                    //    }
                    //    else
                    //        iLinhaInicial = "2";
                    //    foreach (DataColumn iDc in dt.Columns)
                    //    {
                    //        if (iDc.DataType.Name.Trim().Equals("DateTime", StringComparison.OrdinalIgnoreCase))
                    //            pFormatacao.Add(new Formatacao(dt.TableName, ExportExcel.Letra(iDc.Ordinal + 1) + iLinhaInicial, Geral._FormatoData));
                    //    }
                    //}
                }
                #endregion

                // Copy each DataTable
                foreach (System.Data.DataTable iDtPlan in pDataSet.Tables)
                {
                    #region ajustes iniciais
                    //TODO: adicionar opção para escrever na planilha os filtros
                    // e tb. escrever: "Importado em 14/12/2011 por TFTSSYSTEM"

                    Int32 iInicio = 1;
                    if (pFiltros != null && pFiltros.Count > 0)
                    {
                        foreach (Filtros item in pFiltros)
                        {
                            if (item.Planilha != null && iDtPlan.TableName.Trim().Equals(item.Planilha.Trim(), StringComparison.OrdinalIgnoreCase))
                                iInicio++;
                        }
                    }

                    // Copy the DataTable to an object array
                    object[,] rawData = new object[iDtPlan.Rows.Count + iInicio, iDtPlan.Columns.Count];

                    Int32 iContadorCab = 0;
                    if (pFiltros != null && pFiltros.Count > 0)
                    {
                        foreach (Filtros item in pFiltros)
                        {
                            if (item.Planilha != null && iDtPlan.TableName.Trim().Equals(item.Planilha.Trim(), StringComparison.OrdinalIgnoreCase))
                            {
                                rawData[iContadorCab, 0] = item.Filtro;
                                //O valor dos filtros será adicionado depois para o Autofit não fazer efeito neles
                                //rawData[iContadorAux, 1] = item.Valor;
                                iContadorCab++;
                            }
                        }
                    }

                    // Copy the column names to the first row of the object array
                    for (int col = 0; col < iDtPlan.Columns.Count; col++)
                    {
                        //rawData[0, col] = dt.Columns[col].ColumnName;
                        rawData[iInicio - 1, col] = iDtPlan.Columns[col].ColumnName;
                    }
                 
                    // Create a new Sheet
                    Worksheet excelSheet = (Worksheet)excelWorkbook.Sheets.Add(
                        excelWorkbook.Sheets.get_Item(++sheetIndex),
                        Type.Missing, 1, XlSheetType.xlWorksheet);
                    excelSheet.Name = iDtPlan.TableName;
                    //Worksheet excelSheetORIGEM = (Worksheet)excelWorkbook.Sheets.get_Item("Plan1");
                    //excelSheetORIGEM.Activate();
                    //excelSheetORIGEM.Cells.Select();
                    //excelSheetORIGEM.Copy((Object)System.DBNull.Value, (Object)System.DBNull.Value);

                    //excelSheet.Activate();
                    //excelSheet.Cells.Select();
                    //excelSheetORIGEM.Paste(excelSheet, (Object)System.DBNull.Value);

                    List<Formatacao> iLong = new List<Formatacao>();

                    if (TotalCol != null)
                        TotalCol("Gerando planilha: " + iDtPlan.TableName, iDtPlan.Columns.Count, pLblCol, pPrgCol);

                    String iTpColuna;
                    String iRow;
                    DataView iDv;

                    if (TotalRow != null)
                        TotalRow(iDtPlan.Rows.Count, pPrgRow);

                    int iRowX = 0;
                    iDtPlan.Columns.Add("Nro_ControleXYZ", typeof(int));
                    foreach (DataRow iDr in iDtPlan.Rows)
                    {
                        iDr["Nro_ControleXYZ"] = iRowX;
                        iRowX++;
                        if (ProgressoRow != null)
                            ProgressoRow(iRowX, pPrgRow);
                    }
                    #endregion

                    #region Copy the values to the object array
                    for (int col = 0; col < iDtPlan.Columns.Count-1; col++)
                    {
                        //if (TotalRow != null)
                        //    TotalRow(iDtPlan.Rows.Count, pPrgRow);

                        iDv = new DataView(iDtPlan, String.Format("[{0}] is not null", iDtPlan.Columns[col].ColumnName), "", DataViewRowState.CurrentRows);

                        //var col_Branco = (from r in dt.AsEnumerable()
                        //               where r.Field<String>(dt.Columns[col].ColumnName) != null
                        //                  select r.Field<String>(dt.Columns[col].ColumnName)).ToList();

                        //if (col_Branco.Count() > 0)
                        if (iDv.Count > 0)
                        {
                            iTpColuna = iDtPlan.Columns[col].DataType.Name;
                            //if (row == 2 && (col == 14 || col == 22) && dt.TableName.Trim().Equals("Notas de Débitos", StringComparison.OrdinalIgnoreCase))
                            //if (col == 2)
                            //{

                            //}

                            //essa conversão pra datas tb. não funciona
                            //rawData[row + iInicio, col] = Convert.ToDateTime(dt.Rows[row].ItemArray[col]).ToString(Geral._FormatoDataHora);  //se converter para string acaba detonando a formatacao no excel                      

                            if (iTpColuna.Equals("DateTime", StringComparison.OrdinalIgnoreCase))
                            {
                                //for (int row = 0; row < dt.Rows.Count; row++)
                                Int32 row;
                                foreach (DataRowView iDrv in iDv)
                                {
                                    row = int.Parse(iDrv["Nro_ControleXYZ"].ToString());
                                    iRow = iDtPlan.Rows[row].ItemArray[col].ToString();
                                    if (Validacao.IsDate(iRow) && Convert.ToDateTime(iRow) < new DateTime(1900, 1, 1))
                                        //senão fizer isso gera os efeitos abaixo, pois o excel não aceita datas abaixo de 1900
                                        // --> 23/02/0201 não gera erro, mas no excel fica vários cerquilhos e se acionar F2 mostra -620492 ( ############################################################################################################################################################################################################################################################### )
                                        // --> 11/12/0009 gera o erro "Not a legal OleAut date."
                                        rawData[row + iInicio, col] = "'" + Convert.ToDateTime(iRow).ToString(Geral._FormatoDataHora);
                                    // --> com isso no excel irá ficar '23/02/0201 00:00:00 (não mostrando o ' pois no excel ele indica que é um texto)
                                    else
                                        rawData[row + iInicio, col] = iRow; //se converter para string acaba detonando a formatacao no excel

                                    if (ProgressoRow != null)
                                        ProgressoRow(row + 1, pPrgRow);
                                }
                            }
                            //else if ( iTpColuna.Equals("Double", StringComparison.OrdinalIgnoreCase)
                            //    || iTpColuna.Equals("Decimal", StringComparison.OrdinalIgnoreCase))
                            //{
                            //    for (int row = 0; row < dt.Rows.Count; row++)
                            //    {
                            //        rawData[row + iInicio, col] = dt.Rows[row].ItemArray[col].ToString(); //se converter para string acaba detonando a formatacao no excel

                            //        if (ProgressoRow != null)
                            //            ProgressoRow(row + 1, pPrgRow);
                            //    }
                            //}
                            else if (iTpColuna.Equals("String", StringComparison.OrdinalIgnoreCase))
                            {
                                //iDv = new DataView(dt, "Substring(" + dt.Columns[col].ColumnName + ",0,1) = '=' or Substring(" + dt.Columns[col].ColumnName + ",0,1) = '+' or Substring(" + dt.Columns[col].ColumnName + ",0,1) = '-' or LEN(" + dt.Columns[col].ColumnName + ")>8203", "", DataViewRowState.CurrentRows);

                                //if (iDv.Count > 0)
                                {
                                    //for (int row = 0; row < dt.Rows.Count; row++)
                                    Int32 row;
                                    foreach (DataRowView iDrv in iDv)
                                    {
                                        row = int.Parse(iDrv["Nro_ControleXYZ"].ToString());
                                        iRow = iDtPlan.Rows[row].ItemArray[col].ToString();
                                        //esse tratamento é feito pois o excel quando recebe o caracter "=" ou "+" ou "-" na primeira posição gera o erro abaixo, pois tenta construir fórmula
                                        // -2146827284 Exception from HRESULT: 0x800A03EC
                                        if (!Validacao.IsEmpty(iRow) && (iRow.Substring(0, 1).Equals("=") || iRow.Substring(0, 1).Equals("+") || iRow.Substring(0, 1).Equals("-")))
                                            iRow = "'" + iRow;
                                        //Lenght 8203 OK, 8204 gera erro, com isso foi feito o esquema abaixo para ser atualizado depois a planilha, ver em:
                                        //http://dutchgemini.wordpress.com/2012/03/21/error-2147467259-method-copyfromrecordset-of-object-range-failed/
                                        //if (iRow.Length > 8203)
                                        if (iRow.Length > iMaxLong)
                                        {
                                            //iLong.Add(new Formatacao((sheetIndex).ToString(), (row + 2).ToString(), (col + 1).ToString(), iAux));
                                            iLong.Add(new Formatacao((sheetIndex).ToString(), (row + iInicio + 1).ToString(), (col + 1).ToString(), iRow));
                                            //iAux = iAux.Substring(0, 8203);
                                            //excelSheet.Cells[row + 2, col + 1] = iAux;
                                            iRow = string.Empty;
                                        }
                                        rawData[row + iInicio, col] = iRow;

                                        if (ProgressoRow != null)
                                            ProgressoRow(row + 1, pPrgRow);
                                    }
                                }
                                //else
                                //{
                                //    for (int row = 0; row < dt.Rows.Count; row++)
                                //    {
                                //        rawData[row + iInicio, col] = dt.Rows[row].ItemArray[col].ToString();

                                //        if (ProgressoRow != null)
                                //            ProgressoRow(row + 1, pPrgRow);
                                //    }
                                //}
                            }
                            else
                            {
                                Int32 row;
                                foreach (DataRowView iDrv in iDv)
                                {
                                    row = int.Parse(iDrv["Nro_ControleXYZ"].ToString());
                                    rawData[row + iInicio, col] = iDtPlan.Rows[row].ItemArray[col].ToString();

                                    if (ProgressoRow != null)
                                        ProgressoRow(row + 1, pPrgRow);
                                }

                                //for (int row = 0; row < dt.Rows.Count; row++)
                                //{
                                //    rawData[row + iInicio, col] = dt.Rows[row].ItemArray[col].ToString();

                                //    if (ProgressoRow != null)
                                //        ProgressoRow(row + 1, pPrgRow);
                                //}
                            }
                        }
                        if (ProgressoCol != null)
                            ProgressoCol(col + 1, pPrgCol);
                    }
                    iDtPlan.Columns.Remove("Nro_ControleXYZ");
                    #endregion
                    if (iDtPlan.Columns.Count > 0)
                    {

                        #region ajustes antes importação
                        // Calculate the final column letter
                        string finalColLetter = string.Empty;
                        //string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
                        //int colCharsetLen = colCharset.Length;

                        //if (dt.Columns.Count > colCharsetLen)
                        //{
                        //    finalColLetter = colCharset.Substring(
                        //        (dt.Columns.Count - 1) / colCharsetLen - 1, 1);
                        //}

                        //finalColLetter += colCharset.Substring(
                        //        (dt.Columns.Count - 1) % colCharsetLen, 1);

                        finalColLetter = Letra(iDtPlan.Columns.Count);
                        //finalColLetter = Letra(dt.Columns.Count + 74);

                        // Fast data export to Excel
                        string excelRange = string.Format(iLetraDoInicio + "1:{0}{1}", finalColLetter, iDtPlan.Rows.Count + iInicio);

                        iRange = excelSheet.get_Range(excelRange, Type.Missing);

                        #endregion

                        #region formatação geral
                        //iRange.Cells.VerticalAlignment
                        //iRange.Borders[XlBordersIndex.xlEdgeBottom];

                        //if (pFiltros == null || pFiltros.Count < 1)
                        //{

                        //}
                        if (!Validacao.IsEmpty(pFonte) && !pFonte.Equals("Padrão"))
                            iRange.Font.Name = pFonte;
                        if (!Validacao.IsEmpty(pAlinhamento))
                        {
                            switch (pAlinhamento)
                            {
                                case "xlHAlignCenter":
                                    iRange.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter;
                                    break;
                                case "xlHAlignCenterAcrossSelection":
                                    iRange.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenterAcrossSelection;
                                    break;
                                case "xlHAlignDistributed":
                                    iRange.Cells.HorizontalAlignment = XlHAlign.xlHAlignDistributed;
                                    break;
                                case "xlHAlignFill":
                                    iRange.Cells.HorizontalAlignment = XlHAlign.xlHAlignFill;
                                    break;
                                case "xlHAlignGeneral":
                                    iRange.Cells.HorizontalAlignment = XlHAlign.xlHAlignGeneral;
                                    break;
                                case "xlHAlignJustify":
                                    iRange.Cells.HorizontalAlignment = XlHAlign.xlHAlignJustify;
                                    break;
                                case "xlHAlignLeft":
                                    iRange.Cells.HorizontalAlignment = XlHAlign.xlHAlignLeft;
                                    break;
                                case "xlHAlignRight":
                                    iRange.Cells.HorizontalAlignment = XlHAlign.xlHAlignRight;
                                    break;
                                case "xlVAlignCenter":
                                    iRange.Cells.VerticalAlignment = XlVAlign.xlVAlignCenter;
                                    break;
                                case "xlVAlignTop":
                                    iRange.Cells.VerticalAlignment = XlVAlign.xlVAlignTop;
                                    break;
                                case "xlVAlignBottom":
                                    iRange.Cells.VerticalAlignment = XlVAlign.xlVAlignBottom;
                                    break;
                                case "xlVAlignDistributed;":
                                    iRange.Cells.VerticalAlignment = XlVAlign.xlVAlignDistributed;
                                    break;
                                default:
                                    break;
                            }
                        }
                        if (pBordas)
                            iRange.Borders.LineStyle = XlHAlign.xlHAlignGeneral;
                        if (pZoom != 0)
                            excelWorkbook.Application.ActiveWindow.Zoom = pZoom;
                        if (!pDisplayGridlines)
                            excelWorkbook.Application.ActiveWindow.DisplayGridlines = pDisplayGridlines;
                        if (pCongelar)
                        {// Fix first row
                            excelWorkbook.Activate();
                            if (pFiltros == null)
                                excelWorkbook.Application.ActiveWindow.SplitRow = 1;
                            else
                            {
                                var resultFormatacao = pFiltros.Where(f => f.Planilha != null && f.Planilha.Trim().Equals(iDtPlan.TableName.Trim(), StringComparison.OrdinalIgnoreCase));
                                //iContLinha += resultFormatacao.Count();
                                if (resultFormatacao == null)
                                    excelWorkbook.Application.ActiveWindow.SplitRow = 1;
                                else
                                    excelWorkbook.Application.ActiveWindow.SplitRow = 1 + resultFormatacao.Count();
                            }
                            excelWorkbook.Application.ActiveWindow.FreezePanes = true;
                        }
                        #endregion

                        #region importando dados
                        if (TotalCol != null)
                            TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Importando Dados", iDtPlan.Columns.Count, pLblCol, pPrgCol);

                        iRange.Value2 = rawData;
                        #endregion

                        #region testes
                        //excelSheet.get_Range(excelRange, Type.Missing).Value2 = rawData;

                        //excelSheet.get_Range(excelRange).Value2 = rawData;

                        //Range workingRangeCells = excelSheet.get_Range("A" + iContadorAux);
                        //workingRangeCells.MergeArea.get_Range("A" + iContadorAux, "B" + iContadorAux);
                        //workingRangeCells.MergeArea.Activate();
                        //workingRangeCells.Value = item.Filtro;


                        //Microsoft.Office.Interop.Excel.Range iItemFormat;
                        //iItemFormat = excelApp.get_Range("A" + iContadorAux, "B" + iContadorAux);
                        //if (item.Cor != null)
                        //    iItemFormat.Font.Color = ColorTranslator.ToWin32((Color)item.Cor);
                        //if (item.Bold != null)
                        //    iItemFormat.Font.Bold = item.Bold;
                        ////iItemFormat.Borders.LineStyle = Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous;

                        // Mark the first row as BOLD
                        //((Range)excelSheet.Rows[1, Type.Missing]).Font.Bold = true;
                        #endregion

                        #region Formatação
                        Int32 iContAux = 1;
                        if (pFormatacao != null && pFormatacao.Count > 0)
                        {
                            var resultFormatacao = pFormatacao.Where(f => f.Planilha != null && f.Planilha.Trim().Equals(iDtPlan.TableName.Trim(), StringComparison.OrdinalIgnoreCase));

                            if (TotalCol != null)
                                TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Formatação", resultFormatacao.Count(), pLblCol, pPrgCol);

                            //if (TotalRow != null)
                            //    TotalRow(resultFormatacao.Count(), pPrgRow);

                            foreach (Formatacao item in resultFormatacao)
                            {
                                if (ProgressoCol != null)
                                    ProgressoCol(iContAux++, pPrgCol);
                                //if (dt.TableName.Trim().Equals(item.Planilha.Trim(), StringComparison.OrdinalIgnoreCase))
                                {
                                    Microsoft.Office.Interop.Excel.Range celulas;
                                    //if (!Validacao.IsEmpty(item.Cell1) && !Validacao.IsEmpty(item.NumberFormat))
                                    if (!Validacao.IsEmpty(item.Cell1))
                                    {
                                        String iCell2;
                                        if (Validacao.IsEmpty(item.Cell2))
                                        {
                                            if (Validacao.IsNumber(item.Cell1.Substring(1, 1)))
                                                iCell2 = item.Cell1.Substring(0, 1) + (iDtPlan.Rows.Count + 1 + iContadorCab).ToString();
                                            else if (Validacao.IsNumber(item.Cell1.Substring(2, 1)))
                                                iCell2 = item.Cell1.Substring(0, 2) + (iDtPlan.Rows.Count + 1 + iContadorCab).ToString();
                                            else
                                                iCell2 = item.Cell1.Substring(0, 3) + (iDtPlan.Rows.Count + 1 + iContadorCab).ToString();
                                        }
                                        else
                                            iCell2 = item.Cell2;

                                        celulas = excelSheet.get_Range(item.Cell1, iCell2);

                                        if (item.NumberFormat != null)
                                            celulas.NumberFormat = item.NumberFormat;

                                        if (item.Merge)
                                        {
                                            celulas.Merge();
                                            celulas.HorizontalAlignment = Constants.xlCenter;
                                            //if (!Validacao.IsEmpty(item.NumberFormat))
                                            //    celulas.AddComment(item.NumberFormat);
                                        }

                                        if (item.VAlign != null)
                                        {
                                            switch (item.VAlign)
                                            {
                                                case "Center":
                                                    celulas.VerticalAlignment = XlVAlign.xlVAlignCenter;
                                                    break;
                                                case "Distributed":
                                                    celulas.VerticalAlignment = XlVAlign.xlVAlignDistributed;
                                                    break;
                                                case "Justify":
                                                    celulas.VerticalAlignment = XlVAlign.xlVAlignJustify;
                                                    break;
                                                case "Top":
                                                    celulas.VerticalAlignment = XlVAlign.xlVAlignTop;
                                                    break;
                                                case "Bottom":
                                                    celulas.VerticalAlignment = XlVAlign.xlVAlignBottom;
                                                    break;
                                                default:
                                                    break;
                                            }
                                        }

                                        if (item.HAlign != null)
                                        {
                                            switch (item.HAlign)
                                            {
                                                case "Center":
                                                    celulas.HorizontalAlignment = XlHAlign.xlHAlignCenter;
                                                    break;
                                                case "CenterAcrossSelection":
                                                    celulas.HorizontalAlignment = XlHAlign.xlHAlignCenterAcrossSelection;
                                                    break;
                                                case "Distributed":
                                                    celulas.HorizontalAlignment = XlHAlign.xlHAlignDistributed;
                                                    break;
                                                case "Fill":
                                                    celulas.HorizontalAlignment = XlHAlign.xlHAlignFill;
                                                    break;
                                                case "General":
                                                    celulas.HorizontalAlignment = XlHAlign.xlHAlignGeneral;
                                                    break;
                                                case "Justify":
                                                    celulas.HorizontalAlignment = XlHAlign.xlHAlignJustify;
                                                    break;
                                                case "Left":
                                                    celulas.HorizontalAlignment = XlHAlign.xlHAlignLeft;
                                                    break;
                                                case "Right":
                                                    celulas.HorizontalAlignment = XlHAlign.xlHAlignRight;
                                                    break;
                                                default:
                                                    break;
                                            }
                                        }

                                        if (item.CorFundo != null)
                                        {
                                            celulas.Interior.Color = ColorTranslator.ToWin32((Color)item.CorFundo);
                                            //celulas.Borders.LineStyle = XlLineStyle.xlContinuous;
                                        }
                                        if (item.CorFonte != null)
                                            celulas.Font.Color = ColorTranslator.ToWin32((Color)item.CorFonte);

                                        if (item.Negrito != null)
                                            celulas.Font.Bold = item.Negrito;

                                        if (!Validacao.IsEmpty(item.ValorTexto))
                                        {
                                            celulas.Value2 = item.ValorTexto;
                                            //celulas.Group();
                                        }

                                        //if (item.NumberFormat.IndexOf("yyyy") > -1)
                                        //{
                                        //    Microsoft.Office.Interop.Excel.Range iCelFormat;

                                        //    iCelFormat = excelSheet.get_Range(item.Cell1);
                                        //    //item.NumberFormat = item.NumberFormat.Replace("y", "a");
                                        //    //Console.WriteLine(celulas.CurrentRegion);
                                        //    if (iCelFormat.Value2 != null && Validacao.IsDecimal(iCelFormat.Value2.ToString()))
                                        //    {
                                        //        double dbl = (double)(iCelFormat.Value2);
                                        //        System.DateTime data = System.DateTime.FromOADate(dbl);
                                        //        iCelFormat.Value2 = data;
                                        //    }
                                        //}

                                    }
                                }
                            }

                            ////Formatar Colunas
                            //celulas = excelSheet.get_Range("H2", Type.Missing);
                            //celulas.NumberFormat = "MM/DD/YYYY";

                            //celulas = excelSheet.get_Range("I2", Type.Missing);
                            //celulas.NumberFormat = "MM/DD/YYYY";

                            //celulas = excelSheet.get_Range("M2", Type.Missing);
                            //celulas.NumberFormat = "MM/DD/YYYY";

                            //celulas = excelSheet.get_Range("N2", Type.Missing);
                            //celulas.NumberFormat = "MM/DD/YYYY";

                            //celulas = excelSheet.get_Range("L2", "H10");
                            //celulas.NumberFormat = "#,#0.00";

                            //celulas = excelSheet.get_Range("X2", Type.Missing);
                            //celulas.NumberFormat = "#,#0.00";

                            //celulas = excelSheet.get_Range("Y2", Type.Missing);
                            //celulas.NumberFormat = "#,#0.00";
                        }
                        #endregion

                        #region Cabeçalho
                        if (TotalCol != null)
                            TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Cabeçalho", 0, pLblCol, pPrgCol);

                        Microsoft.Office.Interop.Excel.Range iCab;
                        // CABECALHO - Cor cinza, negrito e Borda.              
                        iCab = excelApp.get_Range(iLetraDoInicio + iInicio, string.Format("{0}{1}", finalColLetter, iInicio));
                        //iCab.Interior.Color = ColorTranslator.ToWin32(Color.LightGray);
                        iCab.Interior.ColorIndex = 49;
                        iCab.Font.Color = ColorTranslator.ToWin32(Color.White);
                        iCab.Font.Bold = true;
                        iCab.Borders.LineStyle = XlLineStyle.xlContinuous;
                        #endregion

                        #region auto-filtro
                        if (pAdicionarFiltro)
                        {
                            if (TotalCol != null)
                                TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Auto Filtro", 0, pLblCol, pPrgCol);
                            iCab.AutoFilter(1, Type.Missing, XlAutoFilterOperator.xlAnd, Type.Missing, true);

                            //aqui o filtro fica na 1º linha
                            //excelSheet.Cells.AutoFilter(iInicio, Type.Missing, XlAutoFilterOperator.xlAnd, Type.Missing, true);
                        }
                        #endregion

                        #region atualizado as celulas das planilha como os valores com mais de 8203 caracteres para 2007 e 910 caracteres para 2003
                        if (iLong != null && iLong.Count > 0)
                        {
                            if (TotalCol != null)
                                TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Ajuste células", iLong.Count, pLblCol, pPrgCol);
                            iContAux = 0;
                            foreach (Formatacao item in iLong)
                            {
                                if (ProgressoCol != null)
                                    ProgressoCol(iContAux++, pPrgCol);
                                //item.Cell1 = é a linha
                                //item.Cell2 = é a coluna
                                //item.NumberFormat = é o Valor

                                //finalColLetter = string.Empty;
                                //if (Convert.ToInt32(item.Cell2) > colCharsetLen)
                                //{
                                //    finalColLetter = colCharset.Substring(
                                //        (Convert.ToInt32(item.Cell2) - 1) / colCharsetLen - 1, 1);
                                //}

                                //finalColLetter += colCharset.Substring(
                                //        (Convert.ToInt32(item.Cell2) - 1) % colCharsetLen, 1);
                                finalColLetter = Letra(Convert.ToInt32(item.Cell2));
                                Range workingRangeCells = excelSheet.get_Range(finalColLetter + item.Cell1);
                                workingRangeCells.Value = item.NumberFormat;
                            }
                        }
                        #endregion

                        //if (!(
                        //        iDtPlan.Rows.Count > 1000 &&
                        //        (
                        //            (iDtPlan.Columns.Contains("ANDAMENTO") && (iDtPlan.TableName == "Andamentos Gerenciais" || iDtPlan.TableName == "Andamentos Processo" || iDtPlan.TableName == "Processos"))
                        //            || (iDtPlan.Columns.Contains("DESCRICAO") && (iDtPlan.TableName == "Agendas" || iDtPlan.TableName == "Processos"))
                        //            || iDtPlan.Columns.Contains("RESUMO_OBJETO") || iDtPlan.Columns.Contains("Observação")
                        //        )
                        //    )
                        //   )
                        {
                            #region auto fit e limites - Colunas

                            //http://www.devmedia.com.br/exportacao-para-o-excel-em-net-formatando-celulas/18115
                            if (TotalCol != null)
                                TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Auto fit colunas", iCab.Columns.Count, pLblCol, pPrgCol);
                            //excelSheet.Columns.AutoFit(); //lento pra caraio com muitas linhas e/ou colunas
                            //if (TotalRow != null)
                            //    TotalRow(iCab.Columns.Count, pPrgCol);
                            iContAux = 1;
                            foreach (Range item in iCab.Columns)
                            {
                                try
                                {
                                    String iLetra = Letra(iDtPlan.Columns[item.Cells.Text.ToString()].Ordinal + 1);
                                    //if (ProgressoRow != null)
                                    //    ProgressoRow(iContAux++, pPrgCol);
                                    if (ProgressoCol != null)
                                        ProgressoCol(iContAux++, pPrgCol);
                                    if (TotalCol != null)
                                        TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Auto fit colunas - " + item.Cells.Text, iCab.Columns.Count, pLblCol, pPrgCol);
                                    //if ((
                                    //    //iDtPlan.Rows.Count > 500 &&
                                    //        //!item.Cells.Text.ToString().Equals("DIAS_SEM_ANDAMENTO", StringComparison.OrdinalIgnoreCase)
                                    //        !item.Cells.Text.ToString().Contains("DATA_ULT_ANDAMENTO")
                                    //        && !item.Cells.Text.ToString().Contains("DIAS_SEM_ANDAMENTO")
                                    //        && !item.Cells.Text.ToString().Contains("TIPO_ANDAMENTO")
                                    //        && !item.Cells.Text.ToString().Contains("DATA_ANDAMENTO")
                                    //        && !item.Cells.Text.ToString().Contains("TP_ANDAMENTO")
                                    //        && !item.Cells.Text.ToString().Contains("DT_ANDAMENTO")
                                    //        &&
                                    //            (
                                    //                item.Cells.Text.ToString().Contains("ANDAMENTO")
                                    //                || item.Cells.Text.ToString().Contains("DESCRICAO")
                                    //                || item.Cells.Text.ToString().Contains("RESUMO_OBJETO")
                                    //                || item.Cells.Text.ToString().Contains("Observação")
                                    //                || item.Cells.Text.ToString().Contains("Ult.Andam.Ger._Textual")
                                    //                || item.Cells.Text.ToString().Contains("Ult.Andam.Proc._Textual")
                                    //                || item.Cells.Text.ToString().Contains("Textual_Data")
                                    //                || item.Cells.Text.ToString().Contains("OBJETOS")
                                    //            )
                                    //    ))
                                    Boolean iTemWrap = false;
                                    if (_ColunasWrap != null)
                                    {
                                        var resultCol = _ColunasWrap.Where(f => f.Planilha != null && f.Planilha.Trim().Equals(iDtPlan.TableName.Trim(), StringComparison.OrdinalIgnoreCase));
                                        iContAux = 0;
                                        if (resultCol.Count() > 0)
                                        {
                                            foreach (ColunasWrap itemCol in resultCol)
                                            {
                                                foreach (String iCol in itemCol.Colunas)
                                                {
                                                    if (iCol.Equals(iLetra, StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        iTemWrap = true;
                                                        break;
                                                    }
                                                }
                                                if (iTemWrap)
                                                    break;
                                            }
                                        }
                                    }

                                    if (iTemWrap)
                                    {
                                        //if (iDtPlan.Rows.Count < 500)
                                        item.EntireColumn.ColumnWidth = 100;
                                    }
                                    else
                                    {
                                        Range workingRangeCells = excelSheet.get_Range(iLetra + iInicio, iLetra + (iDtPlan.Rows.Count + iInicio));
                                        foreach (Range itemCol in workingRangeCells.Columns)
                                            itemCol.AutoFit();

                                        //item.AutoFit(); //só faz no cabeçalho
                                        if (Convert.ToInt32(item.EntireColumn.ColumnWidth) > 100)
                                            item.EntireColumn.ColumnWidth = 100;
                                    }
                                }
                                catch (Exception EX)
                                {//SE DER ERRO NÃO FAZ NADA, devido algumas colunas serem do tipo data "01/11/2015" e no datatable ser "String", ex. "RelContencioso", assim o excel confunde 01/11/2015 para 11/01/2015

                                }
                            }
                            #endregion

                            #region Colunas Wrap (Quebrar Texto Automaticamente)
                            if (_ColunasWrap != null)
                            {
                                var resultCol = _ColunasWrap.Where(f => f.Planilha != null && f.Planilha.Trim().Equals(iDtPlan.TableName.Trim(), StringComparison.OrdinalIgnoreCase));
                                iContAux = 1;
                                if (resultCol.Count() > 0)
                                {
                                    if (TotalCol != null)
                                        TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Quebrar Texto Automaticamente", resultCol.Count(), pLblCol, pPrgCol);

                                    foreach (ColunasWrap itemCol in resultCol)
                                    {
                                        if (ProgressoCol != null)
                                            ProgressoCol(iContAux++, pPrgCol);

                                        if (TotalRow != null)
                                            TotalRow(itemCol.Colunas.Count(), pPrgRow);

                                        Int32 iTotRow = 1;
                                        foreach (String iCol in itemCol.Colunas)
                                        {
                                            if (ProgressoRow != null)
                                                ProgressoRow(iTotRow++, pPrgRow);
                                            if (!Validacao.IsEmpty(iCol))
                                            {
                                                Range workingRangeCells = excelSheet.get_Range(iCol + iInicio, iCol + (iDtPlan.Rows.Count + iInicio));
                                                workingRangeCells.WrapText = true;
                                            }
                                        }
                                    }
                                }
                            }
                            #endregion

                            #region auto fit e limites - Linhas
                            //if (TotalCol != null)
                            //    TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Auto fit linhas", 0, pLblCol, pPrgCol);
                            //excelSheet.Rows.AutoFit();
                            if (TotalCol != null)
                                TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Limite altura", iRange.Rows.Count, pLblCol, pPrgCol);

                            //if (TotalRow != null)
                            //    TotalRow(iRange.Rows.Count, pPrgRow);
                            //LIMITE DE ALTURA
                            iContAux = 1;
                            //foreach (Range item in excelSheet.get_Range(excelRange, Type.Missing).Rows)
                            foreach (Range itemRow in iRange.Rows)
                            {
                                //itemRow.Rows.AutoFit();
                                if (Convert.ToInt32(itemRow.EntireRow.RowHeight) > 45)
                                    itemRow.EntireRow.RowHeight = 45;
                                //if (ProgressoRow != null)
                                //    ProgressoRow(iContAux++, pPrgRow);
                                if (ProgressoCol != null)
                                    ProgressoCol(iContAux++, pPrgCol);
                            }
                            #endregion

                            //if (TotalCol != null)
                            //    TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Limite largura", iDtPlan.Columns.Count, pLblCol, pPrgCol);
                            ////LIMITE DE LARGURA
                            //iContAux = 1;
                            //foreach (Range itemCol in iCab.Columns)
                            //{
                            //    if (Convert.ToInt32(itemCol.EntireColumn.ColumnWidth) > 100)
                            //        itemCol.EntireColumn.ColumnWidth = 100;
                            //    if (ProgressoCol != null)
                            //        ProgressoCol(iContAux++, pPrgCol);
                            //}
                        }
                        #region O valor dos filtros será adicionado AGORA para o Autofit não fazer efeito neles
                        iContadorCab = 0;
                        if (pFiltros != null && pFiltros.Count > 0)
                        {
                            iContAux = 0;
                            if (TotalCol != null)
                                TotalCol("Gerando planilha: " + iDtPlan.TableName + " - Filtros - Cabeçalho", pFiltros.Count, pLblCol, pPrgCol);
                            foreach (Filtros item in pFiltros)
                            {
                                if (ProgressoCol != null)
                                    ProgressoCol(iContAux++, pPrgCol);
                                if (item.Planilha != null && iDtPlan.TableName.Trim().Equals(item.Planilha.Trim(), StringComparison.OrdinalIgnoreCase))
                                {
                                    //rawData[iContadorAux, 1] = item.Valor;
                                    Range workingRangeCells = excelSheet.get_Range("B" + (iContadorCab + 1));
                                    workingRangeCells.Value = item.Valor;
                                    iContadorCab++;
                                }
                            }
                            //Microsoft.Office.Interop.Excel.Range celFiltros = excelSheet.get_Range("A1", "A" + iContadorCab);
                            //celFiltros.Rows.Group();
                        }
                        #endregion

                        #region Destacar palavras
                        if (pCelulas != null)
                        {
                            var resultCelulas = pCelulas.Where(f => f.Planilha != null && f.Planilha.Trim().Equals(iDtPlan.TableName.Trim(), StringComparison.OrdinalIgnoreCase));
                            foreach (DestacarCelulas itemCel in resultCelulas)
                            {
                                if (TotalCol != null)
                                    TotalCol("Planilha: " + iDtPlan.TableName + " - buscando palavras ... ", iDtPlan.Rows.Count, pLblCol, pPrgCol);

                                if (TotalRow != null)
                                    TotalRow(itemCel.Celulas.Length, pPrgRow);

                                for (int i = 0; i < iDtPlan.Rows.Count; i++)
                                {
                                    if (ProgressoCol != null)
                                        ProgressoCol(i, pPrgCol);

                                    Int32 iTotRow = 0;
                                    foreach (String iItemCelula in itemCel.Celulas)
                                    {

                                        if (ProgressoRow != null)
                                            ProgressoRow(iTotRow++, pPrgRow);

                                        if (!Validacao.IsEmpty(iItemCelula))
                                        {
                                            Range iItemFormat;
                                            iItemFormat = excelApp.get_Range(iItemCelula + (i + 1 + iInicio).ToString());
                                            String iItemFormatAux = Geral.RemoveAccents(iItemFormat.Text.ToString());

                                            foreach (String iItem in itemCel.Palavras)
                                            {
                                                if (!Validacao.IsEmpty(iItem))
                                                {
                                                    String iItemAux = Geral.RemoveAccents(iItem);
                                                    Int32 iEnc = 0;
                                                    do
                                                    {
                                                        iEnc = iItemFormatAux.IndexOf(iItemAux, iEnc, StringComparison.OrdinalIgnoreCase);
                                                        if (iEnc >= 0)
                                                        {
                                                            iEnc++;
                                                            iItemFormat.Characters[iEnc, iItem.Length].Font.ColorIndex = 3; //3-Red
                                                        }
                                                    }
                                                    while (iEnc >= 0);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        #endregion
                    }
                } //FIM foreach (System.Data.DataTable iDtPlan in pDataSet.Tables)

                // Save and Close the Workbook
                //excelWorkbook.SaveAs(pCamArquivo, XlFileFormat.xlWorkbookNormal, Type.Missing,
                //    Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlExclusive,
                //    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                //excelWorkbook.Save();

                if (pDataSet.Tables.Count > 1)
                    ((Worksheet)excelWorkbook.Sheets[1]).Activate(); //seta o focus na primeira planilha
                excelWorkbook.SaveAs(pCamArquivo);

                //if (pDataSet.Tables.Count > 1)
                //{
                 
                //    aqui
                //    ((Worksheet)excelWorkbook.Sheets[0]).Activate();
                //}
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                #region finalização

                if (iRange != null)
                    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(iRange);

                if (excelWorkbook != null)
                {
                    excelApp.DisplayAlerts = true; //não colocar false, pois em alguns usuários onde não tem o Power Docs gera erro e eles conseguem salvar por aqui, ex. EGSilva
                    excelWorkbook.Close(_SalvarComo, Type.Missing, Type.Missing); //não colocar false, pois em alguns usuários onde não tem o Power Docs gera erro e eles conseguem salvar por aqui, ex. EGSilva                  
                    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excelWorkbook);
                    excelWorkbook = null;
                }
                _SalvarComo = false;
                if (excelApp != null)
                {
                    // Release the Application object
                    excelApp.Quit();
                    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excelApp);
                    excelApp = null;
                }                      

                // Collect the unreferenced objects
                GC.Collect();
                GC.WaitForPendingFinalizers();              

                //volta para pt-BR
                cultura = new System.Globalization.CultureInfo("pt-BR");
                System.Threading.Thread.CurrentThread.CurrentCulture = cultura;
                #endregion
            }
        }

        /*
         *
         * http://stackoverflow.com/questions/7099770/hresult-0x800a03ec-on-worksheet-range
         *
Exception from HRESULT: 0x800A03EC 2012-11-01 10:37:59

We were able to resolve the problem with information from this post, which I quote here for convenience...

Login to the server as a administrator.
Go to "Start" -> "Run" and enter "taskmgr"
Go to the process tab in task manager and check "Show Processes from all users"
If there are any "Excel.exe" entries on the list, right click on the entry and select "End Process"
Close task manager.
Go to "Start" -> "Run" and enter "services.msc"
Stop the service automating Excel if it is running.
Go to "Start" -> "Run" and enter "dcomcnfg"
This will bring up the component services window, expand out "Console Root" -> "Computers" -> "DCOM Config"
Find "Microsoft Excel Application" in the list of components.
Right click on the entry and select "Properties"
Go to the "Identity" tab on the properties dialog.
Select "The interactive user."
Click the "OK" button.
Switch to the services console
Start the service automating Excel
Test you application again.      
         */

    }

    /// <summary>Classe para definição de formatação das céluas ou intervalo de células
    /// </summary>
    /// <example>
    /// <code>
    /// List<Formatacao> iFormat = new List<Formatacao>();
    /// iFormat.Add(new Formatacao("H2", "MM/DD/YYYY"));
    /// iFormat.Add(new Formatacao("I2", "MM/DD/YYYY"));
    /// iFormat.Add(new Formatacao("M2", "MM/DD/YYYY"));
    /// iFormat.Add(new Formatacao("N2", "MM/DD/YYYY"));
    /// iFormat.Add(new Formatacao("L2", "###,###,#0.00"));
    /// iFormat.Add(new Formatacao("X2", "###,###,#0.00"));
    /// iFormat.Add(new Formatacao("Y2", "###,###,#0.00"));
    /// ExportExcel.ExportToExcel(demoDataSet, fastExportFilePath, iFormat);
    /// </code>
    /// </example>
    public class Formatacao
    {
        private string _Planilha;
        private string _Cell1;
        private string _Cell2;
        private string _NumberFormat;
        private Boolean _Merge;
        private Color? _CorFundo;
        private Color? _CorFonte;
        private Boolean? _Negrito;
        private string _ValorTexto;
        private string _VAlign;
        private string _HAlign;
        //        private XlLineStyle _Stilo;

        public string Planilha
        {
            get { return _Planilha; }
        }

        /// <summary>Mostra a célula inicial para formatação
        /// </summary>
        public string Cell1
        {
            get { return _Cell1; }
        }

        /// <summary>Mostra a célula final para formatação
        /// </summary>
        /// <remarks>Caso este campo for omitido, a coluna será formatada da célula definida no campo Cell1 até a última linha</remarks>
        public string Cell2
        {
            get { return _Cell2; }
        }

        /// <summary>Mostra o tipo de formatação
        /// </summary>
        public string NumberFormat
        {
            get { return _NumberFormat; }
            set { _NumberFormat = value; }
        }

        public Boolean Merge
        {
            get { return _Merge; }
            set { _Merge = value; }
        }

        /// <summary>Escreve um valor/texto
        /// </summary>
        public string ValorTexto
        {
            get { return _ValorTexto; }
            set { _ValorTexto = value; }
        }

        /// <summary>Mostra a cor de fundo
        /// </summary>
        public Color? CorFundo
        {
            get { return _CorFundo; }
            set { _CorFundo = value; }
        }

        public Color? CorFonte
        {
            get { return _CorFonte; }
            set { _CorFonte = value; }
        }

        public Boolean? Negrito
        {
            get { return _Negrito; }
            set { _Negrito = value; }
        }

        public string VAlign
        {
            get { return _VAlign; }
            set { _VAlign = value; }
        }

        public string HAlign
        {
            get { return _HAlign; }
            set { _HAlign = value; }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="pCell1">Define a célula inicial para formatação</param>
        /// <param name="pNumberFormat">Define o tipo de formatação</param>
        public Formatacao(String pPlanilha, String pCell1, String pNumberFormat)
        {
            Formatar(pPlanilha, pCell1, null, pNumberFormat, null, null, null);
        }

        public Formatacao(String pPlanilha, String pCell1, String pNumberFormat, String pVAlign, String pHAlign)
        {
            Formatar(pPlanilha, pCell1, null, pNumberFormat, null, null, null, null, false, pVAlign, pHAlign);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, String pVAlign, String pHAlign)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, null, null, null, null, false, pVAlign, pHAlign);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="pCell1">Define a célula inicial para formatação</param>
        /// <param name="pCell2">Define a célula final para formatação, Caso este campo for omitido, a coluna será formatada da célula definida no campo Cell1 até a última linha</param>
        /// <param name="pNumberFormat">Define o tipo de formatação</param>
        public Formatacao(String pPlanilha, String pCell1, String pCell2, String pNumberFormat)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, null, null, null);
        }

        public Formatacao(String pPlanilha, String pCell1, String pNumberFormat, Boolean pNegrito)
        {
            Formatar(pPlanilha, pCell1, null, pNumberFormat, null, null, pNegrito);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, Boolean pNegrito)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, null, null, pNegrito);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, Color pCorFundo)
        {
            Formatar(pPlanilha, pCell1, pCell2, null, pCorFundo, null, null);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, Color pCorFundo, String pValorTexto)
        {
            Formatar(pPlanilha, pCell1, pCell2, null, pCorFundo, null, null, pValorTexto);
        }

        public Formatacao(String pPlanilha, String pCell1, Color pCorFundo)
        {
            Formatar(pPlanilha, pCell1, null, null, pCorFundo, null, null);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, Color? pCorFundo, Color? pCorFonte)
        {
            Formatar(pPlanilha, pCell1, pCell2, null, pCorFundo, pCorFonte, null);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, Color? pCorFundo, Color? pCorFonte, String pValorTexto)
        {
            Formatar(pPlanilha, pCell1, pCell2, null, pCorFundo, pCorFonte, null, pValorTexto);
        }

        public Formatacao(String pPlanilha, String pCell1, Color? pCorFundo, Color? pCorFonte)
        {
            Formatar(pPlanilha, pCell1, null, null, pCorFundo, pCorFonte, null);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, Color? pCorFundo, Boolean? pNegrito)
        {
            Formatar(pPlanilha, pCell1, pCell2, null, pCorFundo, null, pNegrito);
        }

        public Formatacao(String pPlanilha, String pCell1, Color? pCorFundo, Boolean? pNegrito)
        {
            Formatar(pPlanilha, pCell1, null, null, pCorFundo, null, pNegrito);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, Color? pCorFundo, Color? pCorFonte, Boolean? pNegrito)
        {
            Formatar(pPlanilha, pCell1, pCell2, null, pCorFundo, pCorFonte, pNegrito);
        }

        public Formatacao(String pPlanilha, String pCell1, Color? pCorFundo, Color? pCorFonte, Boolean? pNegrito)
        {
            Formatar(pPlanilha, pCell1, null, null, pCorFundo, pCorFonte, pNegrito);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, Color? pCorFundo, Boolean? pNegrito)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, pCorFundo, null, pNegrito);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, Color? pCorFundo,
            Color? pCorFonte, Boolean? pNegrito, String pValorTexto, Boolean pMerge)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, pCorFundo, pCorFonte, pNegrito, pValorTexto, pMerge);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, Color? pCorFundo,
            Color? pCorFonte, Boolean? pNegrito, String pValorTexto, Boolean pMerge, String pVAlign, String HAlign)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, pCorFundo, pCorFonte, pNegrito, pValorTexto, pMerge, pVAlign, HAlign);
        }

        public void Formatar(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, Color? pCorFundo,
            Color? pCorFonte, Boolean? pNegrito)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, pCorFundo, pCorFonte, pNegrito, "");
        }

        public void Formatar(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, Color? pCorFundo,
            Color? pCorFonte, Boolean? pNegrito, String pValorTexto)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, pCorFundo, pCorFonte, pNegrito, pValorTexto, false);
        }


        public void Formatar(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, Color? pCorFundo,
            Color? pCorFonte, Boolean? pNegrito, String pValorTexto, Boolean pMerge, String pVAlign, String pHAlign)
        {
            if (Validacao.IsEmpty(pPlanilha))
                throw new ArgumentNullException("O valor para 'pPlanilha' não pode ser vazio");

            if (Validacao.IsEmpty(pCell1))
                throw new ArgumentNullException("O valor para 'pCell1' não pode ser vazio");

            _Planilha = pPlanilha;
            _Cell1 = pCell1;
            _Cell2 = pCell2;
            _CorFundo = pCorFundo;
            _Negrito = pNegrito;
            _NumberFormat = pNumberFormat;
            _CorFonte = pCorFonte;
            _ValorTexto = pValorTexto;
            _Merge = pMerge;
            _VAlign = pVAlign;
            _HAlign = pHAlign;

        }


        public void Formatar(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, Color? pCorFundo,
            Color? pCorFonte, Boolean? pNegrito, String pValorTexto, Boolean pMerge)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, pCorFundo, pCorFonte, pNegrito, pValorTexto, pMerge, null, null);
        }

        public Formatacao(String pPlanilha, String pCell1, String pCell2, String pNumberFormat, Color? pCorFundo, Color? pCorFonte, Boolean? pNegrito)
        {
            Formatar(pPlanilha, pCell1, pCell2, pNumberFormat, pCorFundo, pCorFonte, pNegrito);
        }
    }

    public class Filtros
    {
        private string _Planilha;
        private string _Filtro;
        private string _Valor;
        private string _Tipo;
        //private Color? _Cor;
        //private Boolean? _Bold;

        public string Planilha
        {
            get { return _Planilha; }
        }
        public string Filtro
        {
            get { return _Filtro; }
        }
        public string Valor
        {
            get { return _Valor; }
            set { _Valor = value; }
        }
        public string Tipo
        {
            get { return _Tipo; }
            set { _Tipo = value; }
        }
        //public Color? Cor
        //{
        //    get { return _Cor; }
        //}
        //public Boolean? Bold
        //{
        //    get { return _Bold; }
        //}

        //public Filtros(string pPlanilha, string pFiltro, string pValor, Color? pCor, Boolean? pBold)
        //{
        //    _Planilha = pPlanilha;
        //    _Filtro = pFiltro;
        //    _Valor = pValor;
        //    _Cor = pCor;
        //    _Bold = pBold;
        //}

        public Filtros(string pPlanilha, string pFiltro, string pValor)
        {
            _Planilha = pPlanilha;
            _Filtro = pFiltro;
            _Valor = pValor;
        }

        public Filtros(string pPlanilha, string pFiltro, string pValor, string pTipo)
        {
            _Planilha = pPlanilha;
            _Filtro = pFiltro;
            _Valor = pValor;
            _Tipo = pTipo;
        }

    }

    public class ColunasWrap
    {
        private string _Planilha;
        private string[] _Colunas;

        public string Planilha
        {
            get { return _Planilha; }
        }

        public string[] Colunas
        {
            get { return _Colunas; }
            set { _Colunas = value; }
        }

        public ColunasWrap(string pPlanilha, string[] pCelulas)
        {
            _Planilha = pPlanilha;
            _Colunas = pCelulas;
        }
    }

    public class DestacarCelulas
    {
        private string _Planilha;
        private string[] _Palavras;
        private string[] _Celulas;

        public string Planilha
        {
            get { return _Planilha; }
        }
        public string[] Palavras
        {
            get { return _Palavras; }
        }
        public string[] Celulas
        {
            get { return _Celulas; }
            set { _Celulas = value; }
        }

        public DestacarCelulas(string pPlanilha, string[] pPalavras, string[] pCelulas)
        {
            _Planilha = pPlanilha;
            _Palavras = pPalavras;
            _Celulas = pCelulas;
        }
    }
}

Datatable transformar linhas em colunas

        public delegate void EventoContaIDs(Int32 pValor, ProgressBar pPrg);
        public delegate void EventoTotalIDs(Int32 pValor, ProgressBar pPrg);
        public event EventoContaIDs ProgressoIDs;
        public event EventoTotalIDs TotalIDs;



        #region Constantes

        /// <summary>Formato de hora sem segundo: "HH:mm"</summary>
        public const String _FormatoHoraSS = "HH:mm";

        /// <summary>Formato de hora com segundo: "HH:mm:ss"</summary>
        public const String _FormatoHoraCS = "HH:mm:ss";

        /// <summary>Formato de data e hora: "dd/MM/yyyy HH:mm:ss"</summary>
        public const String _FormatoDataHora = "dd/MM/yyyy HH:mm:ss";

        /// <summary>Formato de data: "dd/MM/yyyy"</summary>
        public const String _FormatoData = "dd/MM/yyyy";

        /// <summary>Formato de moeda: "###,###,###,###,##0.00"</summary>
        public const String _FormatoMoeda = "###,###,###,###,##0.00";

        /// <summary>Formato de número: "###,###,###,###,##0"</summary>
        public const String _FormatoNumero = "###,###,###,###,##0";

        /// <summary>Formato de Moeda para uso em grids: "{0:N}"</summary>
        public const String _FormatoMoedaGrid = "{0:N}";

        /// <summary>Formato de Data para uso em grids: "{0:dd/MM/yyyy}"</summary>
        public const String _FormatoDataGrid = "{0:dd/MM/yyyy}";

        #endregion

#region transformar linhas em colunas (como o oracle usado atual é o 9 e o comando PIVOT só tem na versão 11 e também os sub-selects estavam muito lentos...)

        public void Transformar_Linhas_Em_Colunas(DataTable iDtPrinc, String pID, DataTable iDtSec, String pColuna)
        {
            Transformar_Linhas_Em_Colunas(iDtPrinc, pID, iDtSec, pColuna, null, null);
        }

        public void Transformar_Linhas_Em_Colunas(DataTable iDtPrinc, String pID, DataTable iDtSec, String pColuna, ProgressBar pPrg1, ProgressBar pPrg2)
        {
            Transformar_Linhas_Em_Colunas(iDtPrinc, pID, iDtSec, pColuna, pPrg1, pPrg2, string.Empty);
        }

        public void Transformar_Linhas_Em_Colunas(DataTable iDtPrinc, String pID, DataTable iDtSec, String pColuna, ProgressBar pPrg1, ProgressBar pPrg2, String pAdicionarNomeTabelaNaColuna)
        {
            if (TotalIDs != null && pPrg1 != null)
                pPrg1.Maximum = iDtPrinc.Rows.Count;

            if (String.IsNullOrEmpty(pColuna))
                Transformar_Linhas_Em_Colunas(iDtPrinc, pID, iDtSec, pPrg1, pPrg2, pAdicionarNomeTabelaNaColuna, false);
            else
            {
                //_DvGroup = null;
                CriarColunas(pColuna, iDtSec, pID, iDtPrinc, pAdicionarNomeTabelaNaColuna);

                //if (TotalIDs != null && pPrg1 != null)
                //    pPrg1.Maximum = iDtPrinc.Rows.Count;

                Int32 iCont = 0;
                foreach (DataRow iDrPrinc in iDtPrinc.Rows)
                {
                    if (!String.IsNullOrEmpty(iDrPrinc[pID].ToString()))
                    {
                        DataView iDvDados = new DataView(iDtSec, pID + "='" + iDrPrinc[pID].ToString() + "'", pColuna, DataViewRowState.CurrentRows);
                        if (iDvDados.Count > 0)
                        {
                            if (ProgressoIDs != null && pPrg2 != null)
                                pPrg2.Maximum = iDvDados.Count;

                            String iMesmo = "";
                            int iAux = 0;
                            Int32 iContAux = 0;
                            foreach (DataRowView iDrSec in iDvDados)
                            {
                                if (!iMesmo.Equals(iDrSec[pColuna].ToString()))
                                    iAux = 0;
                                iAux++;
                                foreach (DataColumn iDc in iDvDados.Table.Columns)
                                {
                                    if (!iDc.ColumnName.Trim().Equals(pID, StringComparison.OrdinalIgnoreCase)
                                        && !iDc.ColumnName.Trim().Equals(pColuna, StringComparison.OrdinalIgnoreCase))
                                    {
                                        iDrPrinc[(String.IsNullOrEmpty(pAdicionarNomeTabelaNaColuna) ? "" : pAdicionarNomeTabelaNaColuna)
                                            + iDrSec[pColuna] + (iAux == 1 ? "" : "_" + iAux) + "_" + iDc.ColumnName] = iDrSec[iDc.ColumnName];
                                    }
                                }
                                iMesmo = iDrSec[pColuna].ToString();
                                if (ProgressoIDs != null && pPrg2 != null)
                                    ProgressoIDs(++iContAux, pPrg2);
                            }
                            //String iMesmo = "";
                            //Int32 iContAux = 1;
                            //foreach (DataRowView iDrSec in iDvDados)
                            //{
                            //    if (!iMesmo.Equals(iDrSec[pColuna].ToString()))
                            //        iContAux = 1;
                            //    foreach (DataColumn iDc in iDvDados.Table.Columns)
                            //    {
                            //        if (!iDc.ColumnName.Trim().Equals(pID, StringComparison.OrdinalIgnoreCase)
                            //            && !iDc.ColumnName.Trim().Equals(pColuna, StringComparison.OrdinalIgnoreCase))
                            //        {
                            //            Boolean iExcecao = false;
                            //            if (_DvGroup != null)
                            //            {
                            //                _DvGroup.RowFilter = pColuna + "='" + iDrSec[pColuna] + "'";
                            //                if (_DvGroup.Count > 0)
                            //                    iExcecao = true;
                            //            }
                            //            iDrPrinc[iDrSec[pColuna] + (iExcecao ? "_" + iContAux : "") + "_" + iDc.ColumnName] = iDrSec[iDc.ColumnName];
                            //        }
                            //    }
                            //    if (!Validacao.IsEmpty(pColuna))
                            //        iMesmo = iDrSec[pColuna].ToString();
                            //    iContAux++;
                            //}

                        }
                    }
                    if (TotalIDs != null && pPrg1 != null)
                        TotalIDs(++iCont, pPrg1);
                }

            }
        }

        //public static T Tipo<T>(String pID, DataTable pDtPrinc)
        //{
        //    return ((pDtPrinc.Columns[pID].DataType == typeof(String)) ? typeof(String) : typeof(Int32));
        //}

        public static List<T> CreateList<T>(params T[] elements)
        {
            return new List<T>(elements);
        }

        private void CriarColunas(String pColuna, DataTable _DtSec, String pID, DataTable pDtPrinc, String pAdicionarNomeTabelaNaColuna)
        {
            //Dictionary<int, string> mydict = new Dictionary<string, int>();

            var queryDtAux = (from table in _DtSec.AsEnumerable()
                              select new
                              {
                                  aColuna = table.Field<String>(pColuna),
                                  aID = table.Field<Int32>(pID) //2014/09/19 -> aID = table.Field<Int32>(pID) alterado de Int32 para String //voltado para Int32 em 24/09/14, pois qdo. tem uma coluna tipo Int32 gera o erro
                              }
                             );
            var queryDt = queryDtAux.ToList();

            var queryGrp = from t in queryDt
                           group t by new { t.aColuna, t.aID } into g
                           select new
                           {
                               aCol = g.Key.aColuna,
                               aIde = g.Key.aID,
                               Total = g.Count()
                           };

            //pega o nº máximo de vezes que a coluna (tipo) vai aparecer por Identificador
            var queryMax = queryGrp
                .GroupBy(i => i.aCol)
                .Select(i => new { NovaColuna = i.Key, MyCount = i.Max(k => k.Total) })
                .OrderBy(i => i.NovaColuna); //order by adicionado em 2014/fev/26

            foreach (var x in queryMax)
            {
                for (int i = 0; i < x.MyCount; i++)
                {
                    foreach (DataColumn iDc in _DtSec.Columns)
                    {
                        if (!iDc.ColumnName.Trim().Equals(pID, StringComparison.OrdinalIgnoreCase)
                            && !iDc.ColumnName.Trim().Equals(pColuna, StringComparison.OrdinalIgnoreCase))
                        {
                            String iColumnName = (String.IsNullOrEmpty(pAdicionarNomeTabelaNaColuna) ? "" : pAdicionarNomeTabelaNaColuna)
                                + x.NovaColuna + (i == 0 ? "" : "_" + (i + 1).ToString()) + "_" + iDc.ColumnName;
                            pDtPrinc.Columns.Add(iColumnName, iDc.DataType);
                            String iFormato = string.Empty;

                            switch (_DtSec.TableName.Trim())
                            {
                                #region Valores
                                case "Valores":
                                    switch (iDc.ColumnName)
                                    {
                                        //case "VALOR_ATUALIZADO":
                                        //case "VALOR_CORRECAO":
                                        //case "VALOR_JUROS":
                                        //    iFormato = Geral._FormatoMoeda + "0000";
                                        //    break;
                                        case "DATA_ATUALIZACAO":
                                        case "QDO_ALTEROU":
                                        case "QDO_INCLUIU":
                                            iFormato = _FormatoDataHora;
                                            break;
                                    }
                                    break;
                                #endregion
                                #region Garantias
                                case "Garantias":
                                    switch (iDc.ColumnName)
                                    {
                                        case "QDO_ALTEROU":
                                        case "QDO_INCLUIU":
                                            iFormato = _FormatoDataHora;
                                            break;
                                    }
                                    break;
                                #endregion
                                #region Dados Clientes
                                case "Dados cliente":
                                    switch (iDc.ColumnName)
                                    {
                                        case "QUANDO":
                                            iFormato = _FormatoDataHora;
                                            break;
                                    }
                                    break;
                                #endregion
                            }
                            if (!String.IsNullOrEmpty(iFormato))
                                pDtPrinc.Columns[iColumnName].ExtendedProperties.Add("Formato", iFormato);
                        }
                    }
                }
            }
        }

        //DataView _DvGroup;
        //private void CriarColunasOLD(String pColuna, DataTable _DtSec, String pID, DataTable pDtPrinc)
        //{
        //    //faz o agrupamento pelo IDE e pelo campo a ser transformado em coluna e desse agrupamento verifica quais registros retornam mais de 1 ocorrência
        //    var groupQuery = from table in _DtSec.AsEnumerable()
        //                     group table by new { column1 = table[pID], column2 = table[pColuna] } into newdr
        //                     where newdr.Count() > 1
        //                     select newdr;

        //    //copia somente a estrutura do datatable
        //    DataTable iDtGroup = _DtSec.Clone();

        //    //copia as linhas que foram encontradas com mais de 1 ocorrência, essas linhas irão gerar a coluna com underline e nº na frente (_n) pois o datatable não aceita colunas com o mesmo nome
        //    foreach (var x in groupQuery)
        //        x.CopyToDataTable(iDtGroup, LoadOption.OverwriteChanges);

        //    //pega todos os campos que irão virar colunas
        //    DataTable iDtDistinct = _DtSec.DefaultView.ToTable(true, pColuna);

        //    //remove os campos que tem mais de 1 ocorrência
        //    var ccList = iDtDistinct.AsEnumerable();
        //    var bannedCCList = iDtGroup.AsEnumerable();
        //    var exceptBanned = from c in ccList
        //                       join b in bannedCCList
        //                          on c.Field<String>(pColuna) equals b.Field<String>(pColuna) into j
        //                       from x in j.DefaultIfEmpty()
        //                       where x == null
        //                       select c;

        //    //insere como colunas todos os campos, exceto os que tem mais de 1 ocorrência
        //    foreach (DataRow iDr in exceptBanned)
        //    {
        //        foreach (DataColumn iDc in _DtSec.Columns)
        //        {
        //            if (!iDc.ColumnName.Trim().Equals(pID, StringComparison.OrdinalIgnoreCase)
        //                && !iDc.ColumnName.Trim().Equals(pColuna, StringComparison.OrdinalIgnoreCase))
        //            {
        //                //if (iDc.ColumnName.Trim().ToUpper().Equals("AND_DTA"))
        //                //{

        //                //}

        //                pDtPrinc.Columns.Add(iDr[pColuna].ToString() + "_" + iDc.ColumnName, iDc.DataType);
        //            }
        //        }
        //    }

        //    _DvGroup = new DataView(iDtGroup, "", pColuna, DataViewRowState.CurrentRows);

        //    //para os campos com mais de 1 ocorrência insere colocando numeração na frente para não repetir (_n)
        //    String iMesmo = "";
        //    Int32 iContAux = 1;
        //    foreach (DataRowView iDr in _DvGroup)
        //    {
        //        if (!iMesmo.Equals(iDr[pColuna].ToString()))
        //            iContAux = 1;
        //        foreach (DataColumn iDc in _DtSec.Columns)
        //        {
        //            if (!iDc.ColumnName.Trim().Equals(pID, StringComparison.OrdinalIgnoreCase)
        //                && !iDc.ColumnName.Trim().Equals(pColuna, StringComparison.OrdinalIgnoreCase))
        //            {
        //                pDtPrinc.Columns.Add(iDr[pColuna].ToString() + "_" + iContAux.ToString() + "_" + iDc.ColumnName, iDc.DataType);
        //            }
        //        }
        //        iMesmo = iDr[pColuna].ToString();
        //        iContAux++;
        //    }
        //}

        public void Transformar_Linhas_Em_Colunas(DataTable iDtPrinc, String pID, DataTable iDtSec)
        {
            Transformar_Linhas_Em_Colunas(iDtPrinc, pID, iDtSec, null, null, string.Empty, false);
        }

        public void Transformar_Linhas_Em_Colunas(DataTable iDtPrinc, String pID, DataTable iDtSec, ProgressBar pPrg1, ProgressBar pPrg2, String pAdicionarNomeTabelaNaColuna,
            Boolean pValidarValorAnterior)
        {
            Transformar_Linhas_Em_Colunas(iDtPrinc, pID, iDtSec, pPrg1, pPrg2, pAdicionarNomeTabelaNaColuna, pValidarValorAnterior, String.Empty);
        }

        //public void Transformar_Linhas_Em_Colunas(DataTable iDtPrinc, String pID, DataTable iDtSec, ProgressBar pPrg1, ProgressBar pPrg2, String pAdicionarNomeTabelaNaColuna,
        //    Boolean pValidarValorAnterior, String pColunaVerNulos)
        //{
        //    Transformar_Linhas_Em_Colunas(iDtPrinc, pID, iDtSec, pPrg1, pPrg2, pAdicionarNomeTabelaNaColuna, pValidarValorAnterior, pColunaVerNulos, String.Empty);
        //}


        public void Transformar_Linhas_Em_Colunas(DataTable iDtPrinc, String pID, DataTable iDtSec, ProgressBar pPrg1, ProgressBar pPrg2, String pAdicionarNomeTabelaNaColuna,
            Boolean pValidarValorAnterior, String pColunaVerNulos) //, String pColunaVerNulos2
        {
            int iTotalCol = 0;

            String iFiltro = "";
            if (iDtSec.Columns.Contains(pColunaVerNulos))
            {
                String iNaoNulos = pColunaVerNulos + " is not null";
                //if (iDtSec.Columns.Contains(pColunaVerNulos2))
                //    iNaoNulos += " and " + pColunaVerNulos2 + " is not null";
                DataRow[] iDrFilt = iDtSec.Select(iNaoNulos);
                foreach (DataRow iDrF in iDrFilt)
                {
                    iFiltro += "," + iDrF[pID].ToString();
                }
                if (!String.IsNullOrEmpty(iFiltro))
                {
                    iFiltro = pID + " in (" + iFiltro.Substring(1) + ")";
                    iDtPrinc.DefaultView.RowFilter = iFiltro;
                }
            }

            Int32 iCont = 0;
            foreach (DataRowView iDrPrinc in iDtPrinc.DefaultView)
            {
                DataView iDvDados = new DataView(iDtSec, pID + "='" + iDrPrinc[pID].ToString() + "'", "", DataViewRowState.CurrentRows);

                if (iDvDados.Count > 0)
                {
                    if (iDvDados.Count > iTotalCol)
                    {
                        //iTotalCol = iDtSec.Rows.Count;
                        //for (int i = 1; i <= iTotalCol; i++)

                        for (int i = (iTotalCol + 1); i <= iDvDados.Count; i++)
                        {
                            foreach (DataColumn iDc in iDvDados.Table.Columns)
                            {
                                if (!iDtPrinc.Columns.Contains(pAdicionarNomeTabelaNaColuna + iDc.ColumnName + (i == 1 ? "" : "_" + i))
                                    && !iDc.ColumnName.Trim().Equals(pID.Trim(), StringComparison.OrdinalIgnoreCase))
                                    //if (!iDc.ColumnName.Trim().Equals(pID.Trim(), StringComparison.OrdinalIgnoreCase))
                                    iDtPrinc.Columns.Add(pAdicionarNomeTabelaNaColuna + iDc.ColumnName + (i == 1 ? "" : "_" + i), iDc.DataType);
                            }
                        }
                        iTotalCol = iDvDados.Count;
                    }

                    //copia dos dados

                    Int32 iContAux = 0;
                    if (ProgressoIDs != null && pPrg2 != null)
                        pPrg2.Maximum = iDvDados.Count;

                    int iAux = 1;
                    foreach (DataRowView iDrSec in iDvDados)
                    {
                        foreach (DataColumn iDc in iDvDados.Table.Columns)
                        {
                            if (!iDc.ColumnName.Trim().Equals(pID.Trim(), StringComparison.OrdinalIgnoreCase))
                            {
                                if (!pValidarValorAnterior ||
                                    (pValidarValorAnterior && String.IsNullOrEmpty(iDrPrinc[pAdicionarNomeTabelaNaColuna + iDc.ColumnName + (iAux == 1 ? "" : "_" + iAux)].ToString())))
                                    iDrPrinc[pAdicionarNomeTabelaNaColuna + iDc.ColumnName + (iAux == 1 ? "" : "_" + iAux)] = iDrSec[iDc.ColumnName];
                            }
                        }
                        iAux++;
                        if (ProgressoIDs != null && pPrg2 != null)
                            ProgressoIDs(++iContAux, pPrg2);
                    }

                }
                if (TotalIDs != null && pPrg1 != null)
                    TotalIDs(++iCont, pPrg1);
            }
        }

        public static string dataTableToHTML(DataTable dt)
        {
            if (dt.Rows.Count == 0)
                return "";

            StringBuilder builder = new StringBuilder();
            builder.Append("<html>");
            builder.Append("<head>");
            builder.Append("<title>");
            builder.Append("Page-");
            builder.Append(Guid.NewGuid().ToString());
            builder.Append("</title>");
            builder.Append("</head>");
            builder.Append("<body>");
            builder.Append("<table border='1px' cellpadding='5' cellspacing='0' ");
            builder.Append("style='border: solid 1px Silver; font-size: x-small;'>");
            builder.Append("<tr align='left' valign='top'>");
            foreach (DataColumn c in dt.Columns)
            {
                builder.Append("<td align='left' valign='top'><b>");
                builder.Append(c.ColumnName);
                builder.Append("</b></td>");
            }
            builder.Append("</tr>");
            foreach (DataRow r in dt.Rows)
            {
                builder.Append("<tr align='left' valign='top'>");
                foreach (DataColumn c in dt.Columns)
                {
                    builder.Append("<td align='left' valign='top'>");
                    builder.Append(r[c.ColumnName]);
                    builder.Append("</td>");
                }
                builder.Append("</tr>");
            }
            builder.Append("</table>");
            builder.Append("</body>");
            builder.Append("</html>");

            return builder.ToString();
        }

        //private static void CarregarFilhos(DataTable iDtPrinc, DataRow iDrPrinc, ref Int32 iTotalCol, String pID, DataView iDvSec)
        //{
        //    if (iDvSec.Count > 0)
        //    {
        //        if (iDvSec.Count > iTotalCol)
        //        {
        //            //iTotalCol = iDtSec.Rows.Count;
        //            //for (int i = 1; i <= iTotalCol; i++)

        //            for (int i = (iTotalCol + 1); i <= iDvSec.Count; i++)
        //            {
        //                foreach (DataColumn iDc in iDvSec.Table.Columns)
        //                {
        //                    //if (!_DtGeral.Tables[0].Columns.Contains(iDc.ColumnName + "_" + i) && !iDc.ColumnName.Trim().Equals(txtID.Text.Trim(), StringComparison.OrdinalIgnoreCase))
        //                    if (!iDc.ColumnName.Trim().Equals(pID.Trim(), StringComparison.OrdinalIgnoreCase))
        //                        iDtPrinc.Columns.Add(iDc.ColumnName + "_" + i, iDc.DataType);
        //                }
        //            }
        //            iTotalCol = iDvSec.Count;
        //        }

        //        //copia dos dados
        //        int iAux = 1;
        //        foreach (DataRowView iDrSec in iDvSec)
        //        {
        //            foreach (DataColumn iDc in iDvSec.Table.Columns)
        //            {
        //                if (!iDc.ColumnName.Trim().Equals(pID.Trim(), StringComparison.OrdinalIgnoreCase))
        //                    iDrPrinc[iDc.ColumnName + "_" + iAux] = iDrSec[iDc.ColumnName];
        //            }
        //            iAux++;
        //        }

        //    }
        //}

        #endregion

C# funções para abertura de excel

        #region funções para abertura de excel

        public static DataTable XlsxToDataSet(String pFile, String pNomeAba)
        {
            return XlsxToDataSet(pFile, pNomeAba, VerVersaoExcel(), false);
        }

        public static DataTable XlsxToDataSet(String pFile, String pNomeAba, Boolean pNaoUtilizarImex)
        {
            return XlsxToDataSet(pFile, pNomeAba, VerVersaoExcel(), pNaoUtilizarImex);
        }

        public static DataTable XlsxToDataSet(String pFile, String pNomeAba, Int32 pVersao)
        {
            return XlsxToDataSet(pFile, pNomeAba, pVersao, false);
        }

        public static DataTable XlsxToDataSet(String pFile, String pNomeAba, Int32 pVersao, Boolean pNaoUtilizarImex)
        {
            return XlsxToDataSet_2(pFile, pNomeAba, pVersao, pNaoUtilizarImex, false);
        }

        //http://www.connectionstrings.com/excel-2003/
        /// <summary>
        ///
        /// </summary>
        /// <param name="pFile"></param>
        /// <param name="pNomeAba"></param>
        /// <param name="pVersao"></param>
        /// <param name="pImex">"IMEX=1;" tells the driver to always read "intermixed" (numbers, dates, strings etc) data columns as text. Note that this option might affect excel sheet write access negative.</param>
        /// <returns></returns>
        public static DataTable XlsxToDataSet_2(String pFile, String pNomeAba, Int32 pVersao, Boolean pNaoUtilizarImex, Boolean pSegundaTentativa)
        {
            String extension = string.Empty;
            try
            {
                DataSet ds = new DataSet();
                extension = Path.GetExtension(pFile);
                String iImex = (pNaoUtilizarImex ? "" : "IMEX=1;");

                Boolean iVersaoNova = (pVersao >= 12 && extension.Equals(".xlsx", StringComparison.OrdinalIgnoreCase));
                if (pSegundaTentativa)
                    iVersaoNova = !iVersaoNova;

                OleDbDataAdapter MyCommand;
                //HDR=YES;IMEX=1; //Excel 8.0;IMEX=1;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text // SÓ FUNCIONA COM 'HDR=NO;IMEX=1', MAS 'HDR=NO' FICA SEM O CABEÇALHO NA PRIMEIRA LINHA
                OleDbConnection MyConnection;
                if (iVersaoNova) //12.0 -> Excel 2007
                    MyConnection = new OleDbConnection(String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0;{1}""", pFile, iImex));
                //MyConnection = new OleDbConnection(String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0;""", pFile));
                else
                    MyConnection = new OleDbConnection(String.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;{1}""", pFile, iImex));

                MyCommand = new System.Data.OleDb.OleDbDataAdapter(String.Format("SELECT * FROM [{0}$]", pNomeAba), MyConnection);
                MyCommand.TableMappings.Add("Table", "Table");
                MyCommand.Fill(ds);
                MyConnection.Close();

                return ds.Tables[0];
            }
            catch (Exception ex)
            {
                if (pSegundaTentativa || pVersao < 12)
                {
                    if (_ExPrimeiraTentativa == null)
                        _ExPrimeiraTentativa = ex;
                    throw new Exception("Error: " + _ExPrimeiraTentativa.Message.ToString() + Environment.NewLine + Environment.NewLine
                        + "pFile: " + pFile + Environment.NewLine + "pNomeAba: " + pNomeAba + " - pVersao: " + pVersao.ToString() + " - extension: " + extension, ex);
                }
                else
                {
                    _ExPrimeiraTentativa = ex;
                    String iEmail = "seuemail@provedor.com.br";
                    if (ConfigurationManager.AppSettings["email_Erro"] != null)
                        iEmail = ConfigurationManager.AppSettings["email_Erro"].Trim();
                    Email.Enviar("", iEmail, "Erro 1 - Máq: " + WindowsIdentity.GetCurrent().Name + " - Abrir Excel", MontarMsgErro(ex));
                    return XlsxToDataSet_2(pFile, pNomeAba, pVersao, pNaoUtilizarImex, true);
                }
            }
        }
        static Exception _ExPrimeiraTentativa;

        public static DataTable CsvFileToDatatable(string path, bool IsFirstRowHeader)
        {
            string header = "No";
            string sql = string.Empty;
            DataTable dataTable = null;
            string pathOnly = string.Empty;
            string fileName = string.Empty;
            //try
            //{
            pathOnly = Path.GetDirectoryName(path);
            fileName = Path.GetFileName(path);
            sql = @"SELECT * FROM [" + fileName + "]";
            if (IsFirstRowHeader)
            {
                header = "Yes";
            }
            using (OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly +
            ";Extended Properties=\"Text;HDR=" + header + "\""))
            {
                using (OleDbCommand command = new OleDbCommand(sql, connection))
                {
                    using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
                    {
                        dataTable = new DataTable();
                        //dataTable.Locale = CultureInfo.CurrentCulture;
                        adapter.Fill(dataTable);
                    }
                }
                connection.Close();
            }
            //}
            //finally
            //{
            //}
            return dataTable;
        }

        public static String[] GetExcelSheetNames(string excelFile)
        {
            return GetExcelSheetNames(excelFile, VerVersaoExcel());
        }

        /// <summary>
        /// This mehtod retrieves the excel sheet names from
        /// an excel workbook.
        /// </summary>
        /// <param name="excelFile">The excel file.</param>
        /// <returns>String[]</returns>
        public static String[] GetExcelSheetNames(string excelFile, Int32 pVersao)
        {
            //Stopwatch stopwatch = new Stopwatch();
            //stopwatch.Start();

            OleDbConnection objConn = null;
            DataTable dt = null;

            try
            {
                // Connection String. Change the excel file to the file you will search.
                String connString;
                if (pVersao >= 12) //12.0 -> Excel 2007
                    connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelFile + ";Extended Properties=Excel 12.0;";
                else
                    connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelFile + ";Extended Properties=Excel 8.0;";
                // Create connection object by using the preceding connection string.
                objConn = new OleDbConnection(connString);
                // Open connection with the database.
                objConn.Open();
                // Get the data table containg the schema guid.
                dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

                if (dt == null)
                {
                    return null;
                }

                String[] excelSheets = new String[dt.Rows.Count];
                int i = 0;

                // Add the sheet name to the string array.
                foreach (DataRow row in dt.Rows)
                {

                    if (!String.IsNullOrEmpty(row["TABLE_NAME"].ToString()) && (row["TABLE_NAME"].ToString().EndsWith("$") ||
                        row["TABLE_NAME"].ToString().EndsWith("$'")))//checks whether row contains '_xlnm#_FilterDatabase' or sheet name(i.e. sheet name always ends with $ sign)
                    {
                        excelSheets[i] = row["TABLE_NAME"].ToString().Replace("$", "").Replace("'", "");
                        i++;
                    }
                }
                excelSheets = excelSheets.Where(x => !string.IsNullOrEmpty(x)).ToArray();

                //// Loop through all of the sheets if you want too...
                //for (int j = 0; j < excelSheets.Length; j++)
                //{
                //    // Query each excel sheet.
                //}

                return excelSheets;
            }
            catch (Exception)
            {
                throw;
                //return null;
            }
            finally
            {
                // Clean up.
                if (objConn != null)
                {
                    objConn.Close();
                    objConn.Dispose();
                    objConn = null;
                }
                if (dt != null)
                {
                    dt.Dispose();
                    dt = null;
                }
                //stopwatch.Stop();
                //MessageBox.Show(stopwatch.Elapsed.ToString());
            }
        }

        public static Int32 VerVersaoExcel()
        {
            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            String iVersao = excel.Version;

            // Release the Application object
            excel.Quit();
            excel = null;

            // Collect the unreferenced objects
            GC.Collect();
            GC.WaitForPendingFinalizers();

            //System.Globalization.CultureInfo cultura = new System.Globalization.CultureInfo("pt-BR");
            //System.Threading.Thread.CurrentThread.CurrentCulture = cultura;

            Decimal intVersao = 0;
            Decimal.TryParse(iVersao.Replace(".", ","), out intVersao);
            return Convert.ToInt32(intVersao);
        }

        /// <summary>
        /// This mehtod retrieves the excel sheet names from
        /// an excel workbook.
        /// </summary>
        /// <param name="excelFile">The excel file.</param>
        /// <returns>String[]</returns>
        public static String[] GetExcelSheetNamesOld(string excelFile)
        {
            //Stopwatch stopwatch = new Stopwatch();
            //stopwatch.Start();

            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook wb = excel.Workbooks.Open(excelFile);

            String[] excelSts = new String[wb.Sheets.Count];

            int j = 0;
            foreach (Microsoft.Office.Interop.Excel.Worksheet sheet in wb.Sheets)
            {
                excelSts[j] = (sheet.Name);
                j++;
            }

            // Close the Workbook
            wb.Close();
            wb = null;

            // Release the Application object
            excel.Quit();
            excel = null;

            // Collect the unreferenced objects
            GC.Collect();
            GC.WaitForPendingFinalizers();

            //stopwatch.Stop();
            //MessageBox.Show(stopwatch.Elapsed.ToString());

            return excelSts;
        }

        #endregion

C# Montar Mensagem de Erro em HTML

        /// <summary>Rotina que retorna um objeto string contendo uma tabela html com os dados referente ao erro enviado por parâmetro
        /// </summary>
        /// <param name="pObjErr">Objeto Exception com os dados do erro</param>
        /// <returns>Retorna um objeto string contendo uma tabela html com os dados referente ao erro</returns>
        /// <example>Escrevendo diretamente um arquivo:
        /// <code>
        /// Geral.EscreverArquivo(token, Geral.MontarMsgErro(e.Error));
        /// </code>
        /// Armazenando em uma variável para posterior uso:
        /// <code>
        /// iBody = Geral.MontarMsgErro(objErr);
        /// </code>
        /// </example>
        public static string MontarMsgErro(Exception pObjErr)
        {
            string pErrorMsg = pObjErr.Message.ToString();
            string pInner = (pObjErr.InnerException == null ? String.Empty : pObjErr.InnerException.ToString());
            string pType = (pObjErr.GetType().FullName == null ? String.Empty : pObjErr.GetType().FullName.ToString());
            string pStack = (pObjErr.StackTrace == null ? String.Empty : pObjErr.StackTrace.ToString());
            string pTargetSite = (pObjErr.TargetSite == null ? String.Empty : pObjErr.TargetSite.ToString());
            string pSource = (pObjErr.Source == null ? String.Empty : pObjErr.Source.ToString());

            return @"
                <html content=""text/html; charset=UTF-8"">
                    <body bgcolor=""#FFFFFF"">
                    <table width=""85%"" border=""1"" cellspacing=""0"" cellpadding=""1"" bordercolor=""#999999"">
                            <tr bgcolor=""#CCCCFC"">
                                    <td width=""100%"" colspan=""2"" height=""20"">
                                        <div align=""center""><font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#0000CC""><b>Dados do Erro</b></font></div>
                                </td>
                            </tr>            
                        <tr bgcolor=""#CCFFCC"">
                   <td width=""15%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2""><b><font color=""#000000"">Date</font></b></font>
                   </td>
                   <td width=""85%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2""><b><font color=""#000000""> " + DateTime.Now.ToString(_FormatoDataHora) + @"&nbsp;</font></b></font>
                   </td>
                   </tr>
                   <tr bgcolor=""#CCFFCC"">
                   <td width=""15%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">Error Message</font>
                   </td>
                   <td width=""85%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">" + pErrorMsg + @"&nbsp;</font>
                   </td>
                     </tr>
                     <tr bgcolor=""#CCFFCC"">
                       <td width=""15%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">Inner Exception</font>
                   </td>
                       <td width=""85%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">" + pInner + @"&nbsp;</font>
                   </td>
                     </tr>
                     <tr bgcolor=""#CCFFCC"">
                       <td width=""15%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">Exception Type</font>
                   </td>
                       <td width=""85%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">" + pType + @"&nbsp;</font>
                   </td>
                     </tr>
                     <tr bgcolor=""#CCFFCC"">
                       <td width=""15%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">Stack Trace</font>
                   </td>
                       <td width=""85%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">" + pStack + @"&nbsp;</font>
                   </td>
                     </tr>
                   <tr bgcolor=""#CCFFCC"">
                   <td width=""15%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">Target Site</font>
                   </td>
                   <td width=""85%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">" + pTargetSite + @"&nbsp;</font>
                   </td>
                     </tr>
                   <tr bgcolor=""#CCFFCC"">
                   <td width=""15%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">Source</font>
                   </td>
                   <td width=""85%"">
                   <font face=""Verdana, Arial, Helvetica, sans-serif"" size=""2"" color=""#006600"">" + pSource + @"&nbsp;</font>
                   </td>
                     </tr>
                    </table>
                    </body>
                </html>";
        }

Datatable - Transformar colunas em linhas

        public static DataTable Transformar_Colunas_Em_Linhas(DataTable iDt)
        {
            //gera o erro no datagridview "A soma dos valores FillWeight das colunas não pode ultrapassar 65535." - "Sum of the columns' FillWeight values cannot exceed 65535"
            if (iDt.Rows.Count > 0)
            {
                DataTable iDtId = new DataTable();
                iDtId.Columns.Add("Campo");
                iDtId.Columns.Add("Valor");

                for (int i = 1; i < iDt.Rows.Count; i++)
                    iDtId.Columns.Add("Valor_" + (i+1).ToString());

                foreach (DataColumn iDc in iDt.Columns)
                {
                    DataRow iDr = iDtId.NewRow();
                    iDr["Campo"] = iDc.ColumnName.ToString();
                    iDr["Valor"] = iDt.Rows[0][iDc.ColumnName].ToString();
                    for (int i = 1; i < iDt.Rows.Count; i++)
                    {
                        iDr["Valor_" + (i + 1).ToString()] = iDt.Rows[i][iDc.ColumnName].ToString();
                    }
                    iDtId.Rows.Add(iDr);
                }
                return iDtId;
            }
            return null;
        }