C# 比较两个excel文件的差异
我想比较两个输入csv文件,看看是否有添加或删除的行。最好的办法是什么。我没有使用列名,因为并非所有文件的列名都一致C# 比较两个excel文件的差异,c#,winforms,linq,excel,csv,C#,Winforms,Linq,Excel,Csv,我想比较两个输入csv文件,看看是否有添加或删除的行。最好的办法是什么。我没有使用列名,因为并非所有文件的列名都一致 private void compare_btn_Click(object sender, EventArgs e) { string firstFile = firstExcel_txt.Text; var results = ReadExcel(openFileDialog1); stri
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);
}
阅读:
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;
}
如果我能帮上忙,那就太好了 最准确的方法是将二者转换为,在将二者转换为数组时检查差异,使用以下链接获取如何将excel工作表转换为数组的简单示例: 现在您已经将两个excel工作表转换为字节[],您应该通过检查字节数组是否相等来检查它们之间的差异 使用
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");
}
使用System.Linq//序列相等
字节[]FirstExcelFileBytes=null;
字节[]SecondExcelFileBytes=null;
FirstExcelFileBytes=GetFirstExcelFile();
SecondExcelFileBytes=GetSecondExcelFile();
if(FirstExcelFileBytes.SequenceEqual(SecondExcelFileBytes)==true)
{
Show(“数组相等”);
}
其他的
{
Show(“数组不匹配”);
}
有足够多的其他方法可以找到比较字节数组,您应该研究哪种方法最适合您
使用以下链接,检查添加的行、删除的行等内容
我建议您为excel文件的每一行计算一个哈希值,然后您可以继续比较每一行的哈希值,看看它是否与另一个文件上的任何哈希值匹配(参见源代码中的注释) 我还提供了一些类来存储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 ;
}
使用System.Security.Cryptography;
私有无效比较\u btn\u单击(对象发送者,事件参数e)
{
字符串firstFile=firstExcel_txt.Text;
ExcelInfo文件1=ReadExcel(openFileDialog1);
字符串secondFile=secondExcel_txt.Text;
ExcelInfo文件2=ReadExcel(openFileDialog2);
比较Xcels(文件1、文件2);
}
public void CompareExcels(ExcelInfo文件A、ExcelInfo文件B)
{
foreach(fileA.excelRows中的ExcelRow行)
{
//如果fileA行的当前哈希在fileB中不存在,则它已被删除
如果(!fileB.ContainsHash(rowA.hash))
{
WriteLine(“删除的行”+rowA.ToString());
}
}
foreach(文件B.excelRows中的ExcelRowB)
{
//如果fileB行的当前哈希在fileA中不存在,则已添加该哈希
如果(!fileA.ContainsHash(rowB.hash))
{
Console.WriteLine(“添加了行”+rowB.ToString());
}
}
}
公共课
{
公共列表单元格;
公共字节[]散列
公共行政区()
{
lstcell=新列表();
}
公共重写字符串ToString()
{
字符串响应;
resp=string.Empty;
foreach(单元格中的字符串单元格文本)
{
if(resp!=string.Empty)
{
resp=resp+”,“+单元格文本;
}
其他的
{
resp=单元格文本;
}
}
返回响应;
}
公共空间计算hash()
{
字节[]行字节;
字节[]单元字节;
int pos;
int numRowBytes;
//确定存储单个excel行需要多少字节
numRowBytes=0;
foreach(单元格中的字符串单元格文本)
{
numRowBytes+=NumBytes(cellText);
}
//分配空间以计算单行的哈希
rowBytes=新字节[numRowBytes]
pos=0;
//将每个单元格的cellText(转换为字节)连接到单个字节数组中
foreach(单元格中的字符串单元格文本)
{
cellBytes=GetBytes(cellText);
System.Buffer.BlockCopy(cellBytes,0,rowBytes,pos,cellBytes.Length);
pos=cellBytes.Length;
}
哈希=新的MD5CryptoServiceProvider().ComputeHash(行字节);
}
静态整数单位(字符串str)
{
返回str.Length*sizeof(char);
}
静态字节[]获取字节(字符串str)
{
字节[]字节=新字节[NumBytes(str)];
System.Buffer.BlockCopy(str.ToCharArray(),0,bytes,0,bytes.Length);
返回字节;
}
}
公共类ExcelInfo
{
公共列表行;
公共信息
{
excelRows=新列表();
}
公共bool containsHashAsh(字节[]哈希表)
{
布尔发现;
发现=错误;
foreach(ExcelRow中的ExcelRow)
{
found=EqualHash(eRow.hash,hashToLook);
如果(找到)
{
打破
}
}
发现退货;
}
公共静态EqualHash(字节[]hashA,字节[]hashB)
{
布尔·贝夸尔;
int i;
bEqual=假;
if(hashA.Length==hashB.Length)
{
i=0;
而((i