I have a folder include 10 excel files. Each of the excel file contain 5 sheets. I would like to
concatenate every 1st row in 1st sheet of each excel file into new sheet1 in new excel file named 'final' concatenate every 2nd row in 1st sheet of each excel file into new sheet1 in new excel file named 'final' concatenate every 3rd row in 1st sheet of each excel file into new sheet1 in new excel file named 'final' ....
then
concatena开发者_Python百科te every 1st row in 2nd sheet of each excel file into new sheet2 in new excel file named 'final' concatenate every 2nd row in 2nd sheet of each excel file into new sheet2 in new excel file named 'final' concatenate every 3rd row in 2nd sheet of each excel file into new sheet2 in new excel file named 'final' ....
repeatedly...do 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 to excel file 10, sheet 1 etc...
the result 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..
Does anyone can help me?
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
This was quite slow. It took around 3 minutes to finish... The reason is that a connection to Excel automation server is created then destroyed repeatedly in each call to XLSREAD/XLSWRITE. On the plus side, these two functions hide away a lot 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 one time, and tear it down once we are finished, 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 believe there are already submissions on the FEX that do a similar thing...
I'll assume that you've saved each of your excel files as a csv named 'file1.csv', 'file2.csv', etc.
Creative use of the reshape
command helps rearrange the rows.
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
精彩评论