Matlab merges each line from another excel file into a new excel file

I have a folder including 10 excel files. Each excel file contains 5 sheets. I would like to

merge every 1st line in the 1st sheet of each excel file into a new sheet1 into a new excel file named 'final' merge every second line in the 1st sheet of each excel file into a new sheet1 into a new excel file named "final" merge every third line in the 1st sheet of each excel file into a new sheet1 into a new excel file named "final" ....

then

merge every 1st line in the 2nd sheet of each excel file into a new sheet2 into a new excel file named 'final' merge every second line in the 2nd sheet of each excel file into a new sheet2 into a new excel file named "final" merge every third line in the 2nd sheet of each excel file into a new sheet2 into a new excel file named "final" ....

several times ... make for all 5 sheets ...

Example:

excel file 1, sheet1

30 4 1.6 1.2 1.2 1.0 35 16 0.9 0.9 1.5 1.0 40 62 0.9 0.9 1.6 1.2 45 3 0.9 0.9 0.9 0.9 50 1 1.5 1.5 0.8 0.8 

excel file 2, sheet1

 10 1 0.8 0.9 0.9 0.9 15 31 0.9 0.9 1.2 1.6 20 2 0.9 0.9 0.9 0.9 25 3 0.9 0.9 0.9 0.9 30 18 0.9 0.9 0.9 0.9 

excel file 3, sheet1 for Excel 10, sheet 1, etc.

the result that I would like to get

final.xls, sheet1

 30 4 1.6 1.2 1.2 1.0 %1st row of sheet1 in excel file 1 10 1 0.8 0.9 0.9 0.9 %1st row of sheet1 in excel file 2 ... %repeated 1st row of sheet1 in excel file 3 to 10 35 16 0.9 0.9 1.5 1.0 %2nd row of sheet1 in excel file 1 15 31 0.9 0.9 1.2 1.6 %2nd row of sheet1 in excel file 2 ... %repeated 2nd row of sheet1 in excel file 3 to 10 

final.xls, sheet2

 %similar to sheet1 just the data read from sheet2.. 

Can anybody help me?

+1
source share
2 answers

I created 10 .xls files for testing with 5 sheets each. All sheets have 5x6 cells of random numbers. Here is my first solution:

 %# get input XLS files dName = uigetdir('.', 'Select folder containing Excel XLS files'); if dName==0, error('No folder selected'); end files = dir( fullfile(dName,'*.xls') ); files = strcat(dName, filesep, {files.name}'); %' %# prepare output XLS file [fName dName] = uiputfile({'*.xls' 'Excel (*.xls)'}, 'Output File', 'final.xls'); if dName==0, error('No file selected'); end fOut = fullfile(dName,fName); %# process NUM_SHEETS = 5; %# number of sheets per file for s=1:NUM_SHEETS %# extract contents of same sheet from all files numData = cell(numel(files),1); for f=1:numel(files) numData{f} = xlsread(files{f}, s); end %# rearrange data numData = cat(3,numData{:}); numData = reshape(permute(numData,[3 1 2]), [], size(numData,2)); %# write data to corresponding sheet of output XLS file xlswrite(fOut, numData, s); end 

It was pretty slow. It took about 3 minutes to finish ... The reason is that a connection to the Excel Automation Server is created and then destroyed again in each XLSREAD / XLSWRITE call . On the plus side, these two functions hide most of the dirty work needed to interact with Excel and expose an easy-to-use interface.

In my second solution, I manually call the Excel COM API . The advantage is that we initiate it only once and rip it off when done, eliminating a lot of overhead. In fact, this code executes in less than 4 seconds !:

 %# get input XLS files dName = uigetdir('.', 'Select folder containing Excel XLS files'); if dName==0, error('No folder selected'); end files = dir( fullfile(dName,'*.xls') ); files = strcat(dName, filesep, {files.name}'); %' %# get output XLS file [fName dName] = uiputfile({'*.xls' 'Excel (*.xls)'},'Output File','final.xls'); if dName==0, error('No file selected'); end fOut = fullfile(dName,fName); %# open Excel COM Server Excel = actxserver('Excel.Application'); Excel.DisplayAlerts = 0; %# prepare output if ~exist(fOut, 'file') %# create if doesnt exist wb = Excel.workbooks.Add; wb.SaveAs(fOut,1); wb.Close(false); else %# delete existing file delete(fOut); end %# extract contents of input files NUM_SHEETS = 5; data = cell(numel(files),NUM_SHEETS); for f=1:numel(files) wb = Excel.Workbooks.Open(files{f}, 0, true); %# open XLS file for reading assert( wb.sheets.Count == NUM_SHEETS ); for s=1:NUM_SHEETS %# loop over all sheets %# activate sheet, and extract entire content Excel.sheets.get('item',s).Activate(); Excel.Range('A1').Activate(); data{f,s} = cell2num( Excel.ActiveSheet.UsedRange.Value ); end wb.Close(false); %# close XLS file end %# rearrange data D = cell(NUM_SHEETS,1); for s=1:NUM_SHEETS x = cat(3,data{:,s}); D{s} = reshape(permute(x,[3 1 2]), [], size(x,2)); end %# write data to sheets of output XLS file wb = Excel.Workbooks.Open(fOut, 0, false); %# open XLS file for writing while Excel.Sheets.Count < NUM_SHEETS %# create sheets as required Excel.Sheets.Add([], Excel.Sheets.Item(Excel.Sheets.Count)); end for s=1:NUM_SHEETS %# write conents to each sheet cellRange = sprintf('A1:%s%d', 'A'+size(D{s},2)-1, size(D{s},1)); wb.sheets.get('item',s).Activate(); Excel.Range(cellRange).Select(); set(Excel.selection, 'Value',num2cell(D{s})); end wb.Save(); wb.Close(false); %# close XLS file %# cleanup Excel.Quit(); Excel.delete(); clear Excel; 

I already believe representations on FEX that do a similar thing ...

+2
source

I assume that you saved each of your excel files as csv with the name 'file1.csv', 'file2.csv', etc.
Creative use of the reshape helps reorder strings.

 num_row = 2; num_col = 6; num_file = 10; c = cell(num_file ,1); for i=1:num_file file = sprintf('file%i.csv', i); x = csvread(file); c{i} = x'; % transpose so each row is a column end data = cell2mat(c); data = reshape(data, num_col, num_row*num_file; data = data'; transpose back 
0
source

All Articles