代碼如下:
//using一下
//原生excel類庫
using Microsoft.Office.Interop.Excel;
//第三方庫
using Spire.Xls;
//檢測電腦中是否安裝了excel
private static bool isExcelInstalled()
{
Type type = Type.GetTypeFromProgID("Excel.Application");
return type != null;
}
//關(guān)閉excel時使用
private static void CloseProc(string ProcName)//關(guān)閉excel時需要用
{
ArrayList procList = new ArrayList();
string tempName;
foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
{
tempName = thisProc.ProcessName;
procList.Add(tempName);
if (tempName == ProcName)
{
thisProc.Kill(); //當發(fā)送關(guān)閉窗口命令無效時強行結(jié)束進程
}
}
}
public static Queue<Person> EXCEL提取數(shù)據(jù)(string 路徑)
{
Queue<Person> 結(jié)果 = new Queue<Person>();
//自行判斷使用第三方或者excel本身自帶的類庫進行處理(本身自帶的分打開excel和不打開excel兩種)
if (路徑 != null && isExcelInstalled() == false)
{
//有路徑,但是沒安裝excel,執(zhí)行第三方dll來進行處理,可以不用打開excel
//創(chuàng)建新對象
Spire.Xls.Workbook workbook = new Spire.Xls.Workbook();
//打開excel表
workbook.LoadFromFile(路徑);
//獲取活動的sheet
Spire.Xls.Worksheet sheet = workbook.ActiveSheet;
try
{
結(jié)果.Enqueue(new Person("提示:", "第三方DLL提取"));
//提取數(shù)據(jù)
for (int cout = 9; cout <= 99999; cout++)
{
if (sheet.Range[cout, 3].Text != null && sheet.Range[cout, 8].Value2 != null && sheet.Range[cout, 1].Text != "合計")
{
Person p = new Person(sheet.Range[cout, 3].Text, sheet.Range[cout, 8].Text);
結(jié)果.Enqueue(p);
}
else
{
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "第三方提取錯誤");
}
try
{//釋放資源,必須要處理的一步,如果不處理,數(shù)據(jù)比較多的話會造成短時間內(nèi)內(nèi)存被異常占用,直到系統(tǒng)自動回收為止
if (workbook != null)
{
workbook.Dispose();
}
else
{
workbook = null;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "釋放資源錯誤");
}
return 結(jié)果;
}
else if (路徑 != null && isExcelInstalled() == true)
{
//路徑為空,安裝了excel,進行原生excel處理,可以不用打開excel
//判斷路徑是否合法
Microsoft.Office.Interop.Excel.Application app; //應(yīng)用程序
Workbooks wbs;//excel中的 workbooks
Microsoft.Office.Interop.Excel.Workbook wb = null; //workbook
Microsoft.Office.Interop.Excel.Worksheet ws; //worksheet
app = new Microsoft.Office.Interop.Excel.Application();//new一個新對象
wbs = app.Workbooks;//從新對象中取的workbooks
wbs.Application.Visible = false;//不顯示APP操作
app.ScreenUpdating = false;//禁止刷新屏幕
app.DisplayAlerts = false;//是否彈出提示框
try
{
結(jié)果.Enqueue(new Person("提示:", "原生excel提取"));
wb = wbs.Open(路徑);//打開excel表
ws = wb.ActiveSheet;//獲取活動的sheet,一般為第一個sheet
//每個公司表格樣式不同,下面的獲取位置也不同,請自行修改,ZW表格的內(nèi)容是從第9行開始,所以下面 cout=9
//提取數(shù)據(jù),直接從9~99999行中查找編碼和數(shù)量不為空的數(shù)據(jù),為空就停止
for (int cout = 9; cout <= 99999; cout++)
{//下面是從[9,3]9行3列中獲取值,后面9行8列中獲取值,分別代表的是編碼和數(shù)量
if (ws.Cells[cout, 3].Value2 != null && ws.Cells[cout, 8].Value2 != null)
{
//將獲取到的編碼和數(shù)量放進person類中,然后再將person類放入隊列
Person p = new Person(ws.Cells[cout, 3].Value2, ws.Cells[cout, 8].Value2);
結(jié)果.Enqueue(p);
}
else
{
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "原生提取錯誤");
}
try
{//釋放資源,必須要處理的一步,如果不處理,數(shù)據(jù)比較多的話會造成短時間內(nèi)內(nèi)存被異常占用,直到系統(tǒng)自動回收為止
if (wb != null)
{
wb.Close(Type.Missing, Type.Missing, Type.Missing);
}
else
{
wb = null;
}
if (wbs != null)
{
wbs.Close();
}
else
{
wbs = null;
}
if (app != null)
{
app.Quit();
}
else
{
app = null;
}
//GC.Collect();//系統(tǒng)自動回收資源,沒有人為釋放徹底,棄用
//關(guān)閉excel進程,如果不關(guān)閉,也會造成資源被占用,excel進程一堆的情況
CloseProc("EXCEL");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "釋放資源錯誤");
}
return 結(jié)果;
}
else if(路徑 == null && isExcelInstalled() == true)
{
//沒有路徑,但是安裝了excel,此類情況一般用于excel插件,直接進行內(nèi)容處理(必須打開excel)
//此方法必須用VSTO程序,所以這里不使用
結(jié)果.Enqueue(new Person("提示", "此方法不支持"));
return 結(jié)果;
}
else
{
結(jié)果.Enqueue(new Person("提示", "未知方法"));
return 結(jié)果;
}
}
使用方法:
Queue<Person> p;
OpenFileDialog file = new OpenFileDialog();
file.Filter = "Excel表格|*.xls;*xlsx";
DialogResult importDialogResult = file.ShowDialog();
if (importDialogResult == DialogResult.Cancel)
{
return;
}
if (importDialogResult == DialogResult.OK)
{
p = MBCore.EXCEL提取數(shù)據(jù)(file.FileName);//數(shù)據(jù)入隊
foreach (Person str in p)
{//從隊列中預(yù)覽數(shù)據(jù),生產(chǎn)環(huán)境采用出隊方法更好,出來一個數(shù)據(jù)處理一次
if (str.編碼.ToString().Contains("提示"))
{
//.......第一行有提示的處理
}
else
{
//第二行沒有提示的處理
}
}
p.Clear();//清空隊列,清空內(nèi)存中的數(shù)據(jù),當然也可以不用管,系統(tǒng)后期會自動給你處理掉
}
效果如下:

image.png

image.png
完成,后面會越來越復(fù)雜了,需要把前面所有內(nèi)容全部整合,還要處理他們之間的耦合問題(就是一個模塊出問題,其他跟著全GG),后面更新會變慢了,未完待續(xù).........