Comparar dos archivos de excel para las diferencias

Quiero comparar dos entradas de archivos csv para ver si hay filas que se han añadido o eliminado. ¿Cuál es la mejor manera de ir sobre esto. No estoy utilizando los nombres de columna debido a que los nombres de las columnas no son consistentes para todos los archivos.

private void compare_btn_Click(object sender, EventArgs e)
        {
            string firstFile = firstExcel_txt.Text;
            var results = ReadExcel(openFileDialog1);
            string secondFile = secondExcel_txt.Text;
            var results2 = ReadExcel(openFileDialog2);

        }

Lectura:

public object ReadExcel(OpenFileDialog openFileDialog)
        {
            var _excelFile = new ExcelQueryFactory(openFileDialog.FileName);
            var _info = from c in _excelFile.WorksheetNoHeader() select c;
            string header1, header2, header3;
            foreach (var item in _info)
            {
                header1 = item.ElementAt(0);
                header2 = item.ElementAt(1);
                header3 = item.ElementAt(2);
            }
            return _info;
        }

cualquier ayuda sobre cómo podría hacer eso sería genial.

  • Mejor y de forma más precisa sería la de convertir ambos a las matrices de bytes y compararlos cuando ambos están convertidos. El siguiente enlace le ayudará a convertir las hojas de excel a la matriz de bytes: c-sharpcorner.com/UploadFile/1a81c5/…
  • Masriyah usted sólo tiene 3 columnas o simplemente simplificado el código ? Yo no veo de dónde eres mantener el contenido de los archivos de excel para realizar la comparación
  • O usted podría descartar las columnas y el hash al resto. Si el hash de archivos de ambos coinciden, entonces tienen los mismos datos, pie de la letra. Hay una pequeña probabilidad de colisión de hash dependiendo del algoritmo utilizado, pero es tan pequeña que el infierno se congelará antes de que usted consiga una colisión.
  • sí he simplificado las columnas de este post -, ¿cómo puede mantener el contenido de los archivos de excel?
  • Me acaba de agregar y respuesta que muestra una aproximación tanto a almacenar y comparar el contenido de texto de los archivos de excel
InformationsquelleAutor Masriyah | 2013-08-26

2 Kommentare

  1. 1

    Sugiero que calcular un Hash para cada fila del archivo de excel, entonces usted puede seguir adelante y comparar el hash de cada fila para ver si coincide con alguno de hash en el otro archivo (ver comentarios en el código fuente)

    Yo también me han proporcionado algunas de las clases para almacenar el contenido de sus archivos de Excel

    using System.Security.Cryptography;
    
    private void compare_btn_Click(object sender, EventArgs e)
    {
        string firstFile = firstExcel_txt.Text;
        ExcelInfo file1 = ReadExcel(openFileDialog1);
    
        string secondFile = secondExcel_txt.Text;
        ExcelInfo file2 = ReadExcel(openFileDialog2);
    
        CompareExcels(file1,file2) ;
    }    
    
    public void CompareExcels(ExcelInfo fileA, ExcelInfo fileB)
    {
        foreach(ExcelRow rowA in fileA.excelRows)
        {
            //If the current hash of a row of fileA does not exists in fileB then it was removed 
            if(! fileB.ContainsHash(rowA.hash))
            {
                Console.WriteLine("Row removed" + rowA.ToString());
            }
        }
    
        foreach(ExcelRow rowB in fileB.excelRows)
        {
            //If the current hash of a row of fileB does not exists in fileA then it was added 
            if(! fileA.ContainsHash(rowB.hash))
            {
                Console.WriteLine("Row added" + rowB.ToString());
            }
        }
    }
    
    public Class ExcelRow
    {
        public List<String> lstCells ;
        public byte[] hash
    
        public ExcelRow()
        {
            lstCells = new List<String>() ;
        }
        public override string ToString()
        {
            string resp ;
    
            resp = string.Empty ;
    
            foreach(string cellText in lstCells)
            {
                if(resp != string.Empty)
                {
                    resp = resp + "," + cellText ;
                }
                else
                {
                    resp = cellText ;
                }   
            }
            return resp ;
        }       
        public void CalculateHash()
        {
            byte[] rowBytes ;
            byte[] cellBytes ;
            int pos ;
            int numRowBytes ;
    
            //Determine how much bytes are required to store a single excel row
            numRowBytes = 0 ;
            foreach(string cellText in lstCells)
            {
                numRowBytes += NumBytes(cellText) ;
            }       
    
            //Allocate space to calculate the HASH of a single row
    
            rowBytes= new byte[numRowBytes]
            pos = 0 ;
    
            //Concatenate the cellText of each cell, converted to bytes,into a single byte array
            foreach(string cellText in lstCells)
            {
                cellBytes = GetBytes(cellText) ;
                System.Buffer.BlockCopy(cellBytes, 0, rowBytes, pos, cellBytes.Length);
                pos = cellBytes.Length ;
    
            }
    
            hash = new MD5CryptoServiceProvider().ComputeHash(rowBytes);
    
        }
        static int NumBytes(string str)
        {
            return str.Length * sizeof(char);
        }
    
        static byte[] GetBytes(string str)
        {
            byte[] bytes = new byte[NumBytes(str)];
            System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
            return bytes;
        }
    }
    public Class ExcelInfo
    {
        public List<ExcelRow> excelRows ;
    
        public ExcelInfo()
        {
            excelRows = new List<ExcelRow>();
        }
        public bool ContainsHash(byte[] hashToLook)
        {
            bool found ;
    
            found = false ;
    
            foreach(ExcelRow eRow in excelRows)
            {
                found = EqualHash(eRow.hash, hashToLook) ;
    
                if(found)
                {
                    break ;
                }
            }
    
            return found ;
        }
        public static EqualHash(byte[] hashA, byte[] hashB)
        {
            bool bEqual ;
            int i ;
    
            bEqual  = false;
            if (hashA.Length == hashB.Length)
            {
                i = 0;
                while ((i < hashA.Length) && (hashA[i] == hashB[i]))
                {
                    i++ ;
                }
                if (i == hashA.Length)
                {
                    bEqual = true;
                }
            }
            return bEqual ;
        }
    }
    
    public ExcelInfo ReadExcel(OpenFileDialog openFileDialog)
    {
        var _excelFile = new ExcelQueryFactory(openFileDialog.FileName);
        var _info = from c in _excelFile.WorksheetNoHeader() select c;
    
        ExcelRow excelRow ;
        ExcelInfo resp ;
    
        resp = new ExcelInfo() ;
    
        foreach (var item in _info)
        {
            excelRow = new ExcelRow() ;
    
            //Add all the cells (with a for each)
            excelRow.lstCells.Add(item.ElementAt(0));
            excelRow.lstCells.Add(item.ElementAt(1));
            ....
            //Add the last cell of the row
            excelRow.lstCells.Add(item.ElementAt(N));
    
            //Calculate the hash of the row
            excelRow.CalculateHash() ;
    
            //Add the row to the ExcelInfo object
            resp.excelRows.Add(excelRow) ;
        }
        return resp ;
    }
    • para mi regreso en el ReadExcel método return _info es tirar un error de que me falta un molde y no se puede convertir de linq IQuerable a ExcelInfo (ExcelFileReader).
    • lo sentimos acerca de que es necesario «volver resp;»
    • Cuando me encontré con la podía tengo una excepción de referencia nula en mi ReadExcel método en excelRow.lstCells.Add(item.ElementAt(0)) y el mensaje de error: Object reference not set to an instance of an object.
    • el código que he publicado no fue compilada, fue rápidamente escrito en el bloc de notas++, es bueno saber que la idea principal ayudado
    • No hay problema – hay una manera de que realmente podría mostrar lo que los registros se ha quitado o añadido al comparar los dos archivos en el calcular el hash de método?
    • hacer que en el CompareExcels método. Hacer un foreach en cada ExcelRow de utilizado, si el hash de la fila actual no existe en la msib, el que usted puede mostrar que la fila ha sido eliminado. A continuación, hacer un foreach en cada ExcelRow de msib, si la tiene de la fila actual no exis int utilizado, entonces usted puede mostrar que la fila como añadido.
    • Ok gracias voy a seguir adelante con eso. También yo miraba a través de este puede el Operador except se utiliza en este caso?
    • He implementado el CompareExcels método, echa un vistazo al código fuente de nuevo
    • Cuando puse el código que me gustaría conseguir ExcelFileReader.ExcelRow para rowA.toString()
    • ¿Se incluye el método ToString() que he añadido ? Si usted hizo lugar a un punto de interrupción dentro de ese método y ver lo que está sucediendo allí
    • Lo echaba de menos, gracias. pero tengo que ajustar la instrucción if debido a que actualmente se está mostrando cada fila en el archivo, tal como fue removido.
    • crear dos archivos de excel con el mismo fila y comprobar que el hash es el mismo, puede mostrar el contenido de «hash» en el método ToString de la clase ExcelRow
    • el problema parece aquí: ` while ((i < hashA.De longitud) && (hashA[i] == hashB[i]))` la (hashA[i] == hashB[i]) es false, aunque ambos son el mismo.
    • que pedazo de la comparación de hash fue tomada de aquí – Cómo calcular y comparar valores hash mediante el uso de Visual C#support.microsoft.com/kb/307020/en-us
    • sí, me miró de que – he cambiado la instrucción while en el compareFiles método a esto: while ((i < fileB.excelRows.Count()) && (fileB.excelRows[i].rowHash.SequenceEqual(fileA.excelRows[i].rowHash))) sino porque el que mencioné en mi comentario anterior se byte[] no estoy seguro de si yo podría hacer lo mismo
    • Seguir trabajando en que me han proporcionado el 95% de lo que usted necesita sin un compilador, apuesto a que usted puede llegar a detectar lo que está mal o falta

  2. 0

    Forma más precisa sería la de convertir a ambos para matrices de bytes, comprobar las diferencias cuando ambos se convierten en una matriz, utilice el siguiente enlace para una simple ejemplo sobre cómo convertir hojas de excel a un matrices de bytes:

    Convertir Excel a Byte[]

    Ahora se han convertido tanto de sus hojas de excel a un byte[], usted debe comprobar las diferencias mediante la comprobación de si las matrices de bytes son iguales sí o no.

    La comprobación se puede hacer por varios medios como la siguiente con linq:

    using System.Linq; //SequenceEqual
    
     byte[] FirstExcelFileBytes = null;
     byte[] SecondExcelFileBytes = null;
    
     FirstExcelFileBytes = GetFirstExcelFile();
     SecondExcelFileBytes = GetSecondExcelFile();
    
     if (FirstExcelFileBytes.SequenceEqual<byte>(SecondExcelFileBytes) == true)
     {
          MessageBox.Show("Arrays are equal");
     }
     else
     {
         MessageBox.Show("Arrays don't match");
     }

    Hay otras maneras de encontrar comparar matrices de bytes, usted debe hacer algunas investigaciones sobre el que se adapte mejor a ti.

    Utilice el siguiente enlace, para comprobar cosas como Row added, row removed etc.

    Comparar excelsheets

    • Estoy seguro de que esto será de gran ayuda. Yo estaba buscando más en volver algo así como una fila se agregan o eliminan – es que algo posible?
    • El enlace de ayuda en respuesta a ello, la comparación de las matrices de bytes devolverá true o false

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...