最近有這麼一個需求。是精準扶貧的項目。我這裏有兩張表數據。第一張表中有若干條記錄,有縣、鄉、村,證件號碼等字段。如下圖所示,暫且叫A表。
、而另外一張表有如下圖所示的字段,我們把下圖叫B表。我們來看一下,有戶編號,證件編號等字段。
現在要求是用第一個圖(A數據)的證件號碼與第二個圖(B數據)的證件編號來掛接。想取出這樣的結果,兩個字段中對應值相同的數據,將相同部分分證件編號的A表數據放到一個數據表裏,而A表除去相同部分的數據放在一個表裏,B表除去相同數據的部分放在另外一個表裏中。說得有點繞,可以類似這麼理解,就是我們現在有相同兩個矢量量面A、B,疊加,求出共同部分,A中除去共同部分,B中除去共同部分。好了,我們來看一下代碼是怎麼實現的。
首先需要將兩個表的數據分別讀取,然後放到字典中,以證件編號,證件號碼作爲字典的關鍵字。而字典的鍵值對象就是我們定義好一個人口信息類。這樣我們就可以將兩份數據組織起來,使用字典的關鍵字key來判斷,具體的實現可以參考代碼。每次需要創建一個excel文件,我們這裏使用的是Apose.cell來創建、下面我們來看一下實現的代碼。
namespace ExportData
{
public partial class Form1 : Form
{
private String fileName = "";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog file = new OpenFileDialog();
file.Filter = "Excel(*.xlsx)|*.xlsx|Excel(*.xls)|*.xls";
file.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
file.Multiselect = false;
if (file.ShowDialog() == DialogResult.Cancel)
{
return;
}
String path = file.FileName;
string fileSuffix = System.IO.Path.GetExtension(path);
if (string.IsNullOrEmpty(fileSuffix))
{
System.Windows.Forms.MessageBox.Show("文件沒有後綴");
return;
}
fileName = path;
this.tb_filename.Text = fileName;
}
//public void isExsit(List<Dictionary<string, int>> dics,string strHBH) {
private void isExsit(Dictionary<string, PopInfo> dics, string strHBH,PopInfo pop)
{
/*
for (int i = 0; i < dics.Count; i++)
{
if (dics[i].ContainsKey(strHBH))
{
int cnt = dics[i][strHBH];
cnt = cnt + 1;
}
}*/
if (dics.ContainsKey(strHBH))
{
return;
} if (!dics.ContainsKey(strHBH))
{
dics.Add(strHBH, pop);
}
}
public void record(Dictionary<string, int> dics,string strHBH,int cnt)
{
if (dics.ContainsKey(strHBH))
{
return;
} if (!dics.ContainsKey(strHBH))
{
dics.Add(strHBH, cnt);
}
}
public string getBeforEightStr(string strParam) {
string res = "";
try
{
if (strParam.Length<18)
{
return strParam;
}
res = strParam.Substring(0, 18);
return res;
}
catch (Exception)
{
System.Windows.Forms.MessageBox.Show("轉換身份證出現錯誤");
return res;
}
}
public int getNUM(string str_num) {
int res = 0;
try
{
res= int.Parse(str_num);
return res;
}
catch (Exception e)
{
System.Console.WriteLine(e.ToString());
}
return res;
}
private string GetAssemblyPath()
{
string CodeBasePath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
CodeBasePath = CodeBasePath.Substring(8, CodeBasePath.Length - 8);
string[] arrSection = CodeBasePath.Split(new char[] { '/' });
string FolderPath = "";
for (int i = 0; i < arrSection.Length - 1; i++)
{
FolderPath += arrSection[i] + "\\";
}
return FolderPath;
}
private void RUN_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(fileName))
{
System.Windows.Forms.MessageBox.Show("文件爲空");
return;
}
Workbook workbook = new Workbook();
workbook.Open(fileName);
Worksheets worksheets = workbook.Worksheets;
String myfileName = System.IO.Path.GetFileNameWithoutExtension(fileName);
int CNT = worksheets.Count;
List<Dictionary<string, int>> Asheet = new List<Dictionary<string, int>>();
List<Dictionary<string, int>> Bsheet = new List<Dictionary<string, int>>();
Dictionary<string, PopInfo> dicsA = new Dictionary<string, PopInfo>();
Dictionary<string, PopInfo> dicsB = new Dictionary<string, PopInfo>();
for (int i = 0; i < CNT; i++)
{
if(i==0){
Cells cells = workbook.Worksheets[i].Cells;
int maxColum = cells.MaxColumn;
int maxRow = cells.MaxRow;
for (int row = 1; row < maxRow; row++) {
/*戶編號*/
Cell cell_hbh = cells[row, 5];
string StrHBH = cell_hbh.StringValue.Trim();
/*人口數*/
Cell cell_rks = cells[row, 9];
int rks = getNUM(cell_rks.StringValue.Trim());
/*身份證前八位*/
Cell cell_sfz = cells[row, 8];
string StrSFZ = cell_sfz.StringValue.Trim();
//StrSFZ=getBeforEightStr(StrSFZ);
PopInfo popInfo = new PopInfo();
popInfo.setHBH(StrHBH);
popInfo.setHKS(rks);
Cell cell_fz = cells[row, 10];
string str_hz = cell_fz.StringValue.Trim();
if (str_hz.Contains("戶主"))
{
isExsit(dicsA, StrSFZ, popInfo);
}
}
}
if (i==1)
{
Cells cells = workbook.Worksheets[i].Cells;
int maxColum = cells.MaxColumn;
int maxRow = cells.MaxRow;
for (int row = 1; row < maxRow; row++)
{
/*戶編號*/
Cell cell_hbh = cells[row, 6];
string StrHBH = cell_hbh.StringValue.Trim();
/*人口數*/
Cell cell_rs = cells[row, 10];
string str_cnt = cell_rs.StringValue.Trim();
int cnt = getNUM(str_cnt);
/*身份證前八位*/
Cell cell_sfz = cells[row, 9];
string StrSFZ = cell_sfz.StringValue.Trim();
//StrSFZ = getBeforEightStr(StrSFZ);
PopInfo popInfo = new PopInfo();
popInfo.setHBH(StrHBH);
popInfo.setHKS(cnt);
isExsit(dicsB, StrSFZ, popInfo);
}
}
}
if (compareAndExport(dicsA, dicsB))
{
System.Windows.Forms.MessageBox.Show("處理成功");
}
else {
System.Windows.Forms.MessageBox.Show("處理失敗");
}
}
private bool compareAndExport(Dictionary<string, PopInfo> Asheet, Dictionary<string, PopInfo> Bsheet)
{
try
{
Dictionary<string, PopInfo> commonSheet = new Dictionary<string, PopInfo>();
Dictionary<string, PopInfo> onlyASheet = new Dictionary<string, PopInfo>();
Dictionary<string, PopInfo> onlyBSheet = new Dictionary<string, PopInfo>();
foreach (KeyValuePair<string, PopInfo> kvA in Asheet)
{
bool isExistA = false;
foreach (KeyValuePair<string, PopInfo> kvB in Bsheet)
{
string strSFZA = getBeforEightStr(kvA.Key);
string strSFZB = getBeforEightStr(kvB.Key);
if ((strSFZA).Equals(strSFZB))
{
commonSheet.Add(kvA.Key, kvA.Value);
isExistA = true;
break;
}
}
/*如果b中不存在*/
if (!isExistA) {
onlyASheet.Add(kvA.Key, kvA.Value);
}
}
/*第二次遍歷*/
foreach (KeyValuePair<string, PopInfo> kvB in Bsheet)
{
bool isExistB = false;
foreach (KeyValuePair<string, PopInfo> kvA in Asheet)
{
string strSFZA = getBeforEightStr(kvA.Key);
string strSFZB = getBeforEightStr(kvB.Key);
if ((strSFZA).Equals(strSFZB))
{
isExistB = true;
break;
}
}
if (!isExistB)
{
onlyBSheet.Add(kvB.Key, kvB.Value);
}
}
exportDATA(commonSheet, "commonSheet.xls");
exportDATA(onlyASheet, "onlyASheet.xls");
exportDATA(onlyBSheet, "onlyBSheet.xls");
return true;
}
catch (Exception)
{
return false;
}
}
private void exportDATA(Dictionary<string, PopInfo> dics, string fileName)
{
/*創建工作薄*/
Workbook wb = new Workbook();
/*創建樣式*/
Style style = wb.Styles[wb.Styles.Add()];
/*設置單元格水平居中對齊和垂直居中對齊*/
style.HorizontalAlignment = Aspose.Cells.TextAlignmentType.Center;
/*新建工作表*/
Worksheet ws = wb.Worksheets[0];
int row = 0;
foreach (KeyValuePair<string, PopInfo> kv in dics)
{
string key = kv.Key;
//string num = Convert.ToString(kv.Value);
PopInfo pop = kv.Value;
ws.Cells[row, 0].PutValue(key);
ws.Cells[row, 1].PutValue(pop.getHBH());
ws.Cells[row, 2].PutValue(pop.getHKS());
row = row + 1;
}
/*設置所有列爲自適應列寬*/
ws.AutoFitColumns();
string path = GetAssemblyPath();
string filePath = System.IO.Path.Combine(path, fileName);
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
FileStream fs = System.IO.File.Create(filePath);
fs.Close();
wb.Save(filePath);
}
}
}
這裏實現的人口信息類如下所示。非常簡單。
class PopInfo
{
public string hbh;
public int hks;
public PopInfo() { }
public PopInfo(string hbh, int hks)
{
this.hbh = hbh;
this.hks = hks;
}
public string getHBH() {
return this.hbh;
}
public int getHKS() {
return this.hks;
}
public void setHKS(int strHKS)
{
this.hks = strHKS;
}
public void setHBH(string strHBH) {
this.hbh = strHBH;
}
}
注意,這裏使用的是c#編寫的。後面的結果不好展示,這裏給大家展示實現的窗口界面。