VSTO學習筆記(九)淺談Excel內(nèi)容比較
說起文件內(nèi)容比較,或許我們首先想到的是UltraCompare這類專業(yè)比較的軟件,其功能非常強大,能夠?qū)谖谋镜奈募?nèi)容作出快速、準確的比較,有詳細的差異報告,非常便于分析。其實,各種版本控制軟件中也包含有或多或少的比較功能,如TFS、CVS、SVN等。但是如果待比較的文件不是基于文本類型的,那就無能為力了。今天我就來談一談Excel的比較方法及其特點,也和大家共同探討一下,如果你有更好的方法,歡迎分享。
一、Excel的文件架構
Excel的文件結構,一個Excel是一個工作簿,其中可以包含若干個工作表,正式由于這個架構,造成比較Excel中的內(nèi)容比較困難,尤其當工作表中的數(shù)據(jù)量很大時,常規(guī)的比較軟件更是無能為力。
二、三種比較方法
下面我分別用三種方法來比較兩個Excel中的內(nèi)容,首先準備兩個測試Excel,為了簡單起見,兩個Excel都只包含一個工作表,其中填充了一些數(shù)字:
圖1、1.xlsx
圖2、2.xlsx
1、首先我用比較笨的方法,寫一段程序,逐個比較單元格(假設兩個Excel中包含的工作表的命名和個數(shù)完全相同):
代碼
{
this.__int內(nèi)容不同單元格個數(shù) = 0;
this.__dic內(nèi)容不同.Clear();
Excel.Application app = new Excel.Application();
app.DisplayAlerts = false;
Excel.Workbook srcBook = app.Workbooks.Open(v_strSourcePath);
Excel.Workbook destBook = app.Workbooks.Open(v_strDestPath);
FileStream log = new FileStream(System.Windows.Forms.Application.StartupPath + @"\Logs\ReportCheck.log", FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamWriter writer = new StreamWriter(log);
string msg = string.Empty;
writer.WriteLine("*********************************************************************************\n");
foreach (Excel.Worksheet sheet in srcBook.Worksheets)
{
for (int i = 1; i <= sheet.UsedRange.Rows.Count; i++)
{
for (int j = 1; j <= sheet.UsedRange.Columns.Count; j++)
{
string src = sheet.Cells[i, j].Value2 == null ? string.Empty : sheet.Cells[i, j].Value2.ToString();
string dest = destBook.Worksheets[sheet.Name].Cells[i, j].Value2 == null ? string.Empty : destBook.Worksheets[sheet.Name].Cells[i, j].Value2.ToString();
if (src != dest)
{
msg = DateTime.Now.ToString() + "------" + sheet.Name + " 【" + this.fnGetExcelAddress(i, j) + "】單元格中的內(nèi)容不相同\n";
this.__int內(nèi)容不同單元格個數(shù)++;
this.__dic內(nèi)容不同.Add(this.__int內(nèi)容不同單元格個數(shù), msg);
writer.WriteLine(msg);
}
}
}
}
writer.WriteLine("*********************************************************************************\n");
srcBook.Save();
destBook.Save();
app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
System.Runtime.InteropServices.Marshal.ReleaseComObject(srcBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(destBook);
app = null;
srcBook = null;
destBook = null;
GC.Collect();
}
2、使用OpenXML SDK 2.0
前面的文章講過OpenXML SDK及其相關工具的簡單用法,其實還可以用它來比較Excel,當然,僅限于比較Excel 2007、Excel 2010。
如果你還沒有安裝OpenXML SDK 2.0,可以在這里下載。
下載完畢,一步步安裝結束后,就可以使用了。
1)打開Productivity Tool:
2)對這個工具做一些簡單配置:
可以選擇顯示行號、忽略命名空間、忽略聲明:
選擇待比較的Excel版本,我使用的Excel 2010,故選擇第二個:
3)點擊【Compare Files】,然后選擇兩個待比較的Excel文件,點擊【OK】:
4)可以看到Excel被分拆成了一個個part,標記為綠色的表示內(nèi)容中有不同:
5)選擇一個標記為綠色的part,點擊【View Par Diff】,可以查看具體的明細:
這個界面與傳統(tǒng)的比較軟件中的界面非常相似,可以很容易的看出不同之處。
這種方法的缺點是比較結果不夠直觀,難以獲取比較的匯總結果,當數(shù)據(jù)量很大時更是如此。
3、使用SpreadshCompare
SpreadshCompare是國外人寫的一個VBA插件,開源免費,可以在sourceforge上下載,最新版本是1.15,支持Excel 2003,Excel 2007,目前還不支持Excel 2010 x64。由于我使用的是Excel 2010 x64,故暫時在虛擬機中進行測試。
我使用的Hyper-V,安裝了Windows Server 2003 R2,Office 2007。
1)下載完畢安裝后,在Excel的【加載項】中可以看到一個天平的小圖標:
2)先打開兩個待比較的Excel:1.xlsx、2.xlsx,然后分別選擇兩個待比較的Excel,點擊【Next】:
3)選擇逐單元格比較,保持大小寫敏感,其他選項默認:
4)分別選擇待比較的工作表,點擊【Next】:
5)選擇比較所有的區(qū)域,點擊【Next】:
6)選擇生成匯總表選項,保持默認即可:
7)設置工作表的順序,然后點擊【Compare】:
8)首先會給出一個簡短的匯總信息:
9)點擊【確定】后會生成兩個工作簿,一個記錄所有不同之處,另一個給出單元格對比分析:
10)同時對源文件也用顏色進行了標示,黃色表示不同:
經(jīng)過大量數(shù)據(jù)測試,該插件性能很高,速度較快。以后我會試著修改下這個插件的源代碼,爭取支持Excel 2010 x64。
其他類似的還有Compare Spreadsheet For Excel(商業(yè)軟件)、Excel Compare(商業(yè)軟件)、Synkronizer for Excel(商業(yè)軟件)等。
三、小結
本次我們暢談了下Excel的比較問題,給出了三種解決方案,三種方案各有優(yōu)劣,只是適用場合不同,請根據(jù)你的需求進行選擇。


浙公網(wǎng)安備 33010602011771號