中有冒号 文件路径_用Matlab脚本文件实现Excel文件的合并
日常吐槽
前段時間跟同事聊天,同事洗腦了一個新的(扎心的)世界觀,“人生分三個階段,20歲時承認父母很平庸,30歲時承認自己很平庸,40歲時承認孩子很平庸”。這是這位同事在孩子學而思考試后的心得體會,他的年齡請對號入座。我正處在承認自己很平庸的路上肆意奔跑。不過,不光是什么年齡都有權對現實說不。(封面一般是我最近喜歡的電影)
來源
工程師嘛,目的性一般比較強。肯定是看著哪里不爽了,所以想優化方案。
之所以會有實現Excel文件自動合并的想法,是部門一百多人,每次統計個人意愿,體檢信息等內容的時候,都是一個Excel模板,大家修改自己的那一行,然后郵件或者丟到網盤里面,最后一個人打開每個文件要ctrl C+ctrl V把大家的內容合并到一起,這種重復工作毫無意義。
分析如何實現
- 工具:Matlab
- 實現效果:最好能傻瓜式操作,最好能有交互窗口,進度條等,這樣可以提升用戶體驗。
- 實現思路:
1、對話框提示用戶輸入需要合并文件路徑
2、對話框提示用戶輸入要合并的sheet表和范圍(比如A1:C3)
3、將路徑內的文件和范圍寫入到存儲變量中,這個過程可能文件較多,最好有個進度條
4、對話框提示用戶保存的文件路徑和文件名
5、將數據依次保存到指定文件中
6、保存完成后彈出對話框提示用戶完成合并
另外程序需要處理用戶輸入的非法值,比如用戶在打開對話框中并沒有點確定而是點了取消,程序最好能提示報錯。
代碼實現
clear clc %--- 彈出對話框提示用戶選擇要合并文件的路徑Path = uigetdir('','選擇要合并文件路徑');%使用uigetdir調取路徑 %判斷用戶是選擇了路徑還是點了取消 if Path == 0msgbox('路徑選擇無效,請重新運行程序','錯誤','error');%如果用戶點了取消,系統默認會傳遞給path為0,這時彈出對話框提示選擇錯誤,點擊確認程序退出 else%---去除路徑內的無效文件FileList = dir(Path);%使用dir獲取路徑下的文件列表NaN_data_index = find([FileList.bytes]==0);%使用find查找文件列表中空文件FileList(NaN_data_index) = [];%將空文件從文件列表中刪除%---讀取文件%提示用戶輸入excel表格sheet位置及內容范圍trydlgPrompt= {'請輸入要合并的表格位置','請輸入要合并的范圍'}; %兩行提示信息dlgTitle='選擇合并內容';%對話框標題dlgDims=[1 20;1 25];%輸入文本框的尺寸dlgDefinput={'1','A1:H3'};%默認值sheet_num = inputdlg(dlgPrompt,dlgTitle,dlgDims,dlgDefinput);catchwarndlg('輸入錯誤')end%循環讀取文件內容,設置進度條m=0;%初始化,循環用file_path = [];%初始化,后面所有文件的路徑放在這里面data_raw{length(FileList),1} = [];%初始化,后面讀取的數據放在這里面h_waitbar=waitbar(m/length(FileList),'開始讀取');%進度條for m = 1:length(FileList)str_waitbar = ['文件讀取中,已完成:',num2str(m/length(FileList)*100),'%'];%進度條提示語句waitbar(m/length(FileList),h_waitbar,str_waitbar);%進度條更新file_path = fullfile(Path,FileList(m).name);%合并路徑和文件名,便于后面文件讀取[num,text,data] = xlsread(file_path,str2num(sheet_num{1}),sheet_num{2});%讀取文件data_raw{m,1} = data;%循環一次,把data賦值一次endclose(h_waitbar);%關閉進度條%---寫入文件 try[save_name,save_path] = uiputfile('merge_excel_.xlsx');%提示選擇保存的路徑和文件名catchwarndlg('輸入錯誤');end%得到用戶合并文件的行數position_num=split(sheet_num{2},':');%用冒號分割字符串,分別得到一個起點一個終點,如A1;B12re_pattern='[0-9]*';%正則表達式,把數字全部提出start_num=regexp(position_num{1},re_pattern,'match');%把起點的數字提出來,如1;stop_num=regexp(position_num{2},re_pattern,'match');%把終點的數字提出來,如12;range_sep=str2num(stop_num{1})-str2num(start_num{1})+1;%把字符串轉換成數字,相減得間距%寫入操作range_init = 1;%初始化range = 'A1';%初始化for n =1:length(FileList)status = xlswrite(fullfile(save_path,save_name),data_raw{n},1,range);%寫入文件的sheet表默認是1status_num(n,1) = status;range = sprintf('A%d',range_init+n*range_sep);%移動寫入的位置endnum_success=size(status_num);if num_success(1) == length(FileList)%判斷是否已經把全部文件寫完str_success = sprintf('合并完成,共合并%d份文件,成功%d 份',length(FileList),sum(status_num));%顯示的文本內容msgbox(str_success)end clear clc實現效果
excel 原文件是這樣的
把3行進行合并,合并后效果
代碼講解
其實程序的注釋,我已經寫的很詳細,如果還有不清楚的可以看下matlab幫助。這里就對寫程序的時候一些廢了點時間的地方說下:
1、我不知道我的文件夾里看著是有3個excel文件,但是dir讀取后確實5個,其中2個是空的。
windows的實際顯示效果
讀取后FileList的效果
所以加了一段用文件
%---去除路徑內的無效文件 FileList = dir(Path);%使用dir獲取路徑下的文件列表 NaN_data_index = find([FileList.bytes]==0);%使用find查找文件列表中空文件 FileList(NaN_data_index) = [];%將空文件從文件列表中刪除2、在寫入到合并Excel文件的時候需要一個類似指針的東西,不斷將寫入起點下移,這樣避免后面寫入文件覆蓋前面的。但是下移的量需要用‘A1:H13’這個字符串取得,比如這里13-1=12,這個下移量就是12。在這里我處理的方式是先用冒號將字符串分隔,然后用正則表達式分別取出兩個字符串的數字部分,最后實現這兩個數字的相減得到下移量。關于正則表達式需要自己查下,還是很有必要了解下的,之所以用正則表達式,而不是硬生生的把前面的A或者H砍掉,是因為用戶可能會輸入大的行數,比如‘D5:AC123’這時候字母和數字的個數是不定的,無法靠字符串的位來操作。
%得到用戶合并文件的行數position_num=split(sheet_num{2},':');%用冒號分割字符串,分別得到一個起點一個終點,如A1;B12re_pattern='[0-9]*';%正則表達式,把數字全部提出start_num=regexp(position_num{1},re_pattern,'match');%把起點的數字提出來,如1;stop_num=regexp(position_num{2},re_pattern,'match');%把終點的數字提出來,如12;range_sep=str2num(stop_num{1})-str2num(start_num{1})+1;%把字符串轉換成數字,相減得間距不完美
最后想說的是程序是不完美的,為什么暫時先不改了,主要是懶
1、對于用戶的異常操作,比如應該輸入‘A3:H3’,輸入成'A:H',該點確認卻點了取消等等(最不可靠的就是人類),雖然程序里嘗試了if else和try catch,但不是為每個步驟都寫了。
2、把文件全部讀取到data,最后再一股腦兒都寫入,我覺得效率有點低,大文件的話data會很大,占用過多內存。可以讀取一個寫入一個,這樣data數據量有限。其實也好改只需要把寫入的操作放入讀取的for循環中。
3、另外寫入的操作沒有設置進度條。(其實解決了第二個,這個也就不是問題了)。
4、完成這個操作,其實也不算是把合并的工作全部完成,還需要把表頭和序號填充好。剛興趣的自己實踐操作下,實現還是很簡單的。
5、當然前臺小妹一般才不裝matlab,為了方便更多人使用,其實可以用matlab生成可執行exe文件,matlab Runtime了解下。網上教程很多,感興趣的可以看看。
6、其他的歡迎指正探討。有問題可以發我郵箱 283522085@qq.com
總結
以上是生活随笔為你收集整理的中有冒号 文件路径_用Matlab脚本文件实现Excel文件的合并的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ntrip获取源列表_Ntrip协议简介
- 下一篇: 调用第三方接口的几种请求方式