Matlab объединяет каждую строку из другого файла Excel в новый файл Excel - PullRequest
1 голос
/ 21 июля 2011

У меня в папке 10 файлов Excel.Каждый из файлов Excel содержит 5 листов.Я хотел бы

объединить каждую 1-ю строку в 1-м листе каждого файла Excel в новый лист1 в новом файле Excel с именем 'final', объединить каждую 2-ю строку в 1-м листе каждого файла Excel в новый лист1 в новом файле Excelс именем 'final' объединить каждую 3-ю строку в 1-м листе каждого файла Excel в новый лист1 в новом файле Excel с именем 'final' ....

затем

объединить каждую 1-ю строку в 2-м листекаждого файла Excel на новый лист2 в новом файле Excel с именем «final» объединить каждую 2-ю строку на 2-м листе каждого файла Excel в новый лист2 в новом файле Excel с именем «final» объединить каждую 3-ю строку на 2-м листе каждого файла Excel в новыйлист2 в новом файле Excel с именем 'final' ....

несколько раз ... сделать для всех 5 листов ...

пример:

файл Excel 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 2, лист1

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 3, лист 1 для файла Excel 10, лист 1 и т. Д. *

результат, который я хотел бы получитьчтобы получить

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..

Кто-нибудь может мне помочь?

Ответы [ 2 ]

2 голосов
/ 22 июля 2011

Я создал 10 .xls файлов для тестирования по 5 листов в каждом. Все листы имеют 5х6 ячеек случайных чисел. Вот мое первое решение:

%# 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

Это было довольно медленно. Для завершения потребовалось около 3 минут ... Причина в том, что соединение с сервером автоматизации Excel создается, а затем неоднократно уничтожается при каждом вызове XLSREAD / XLSWRITE . С другой стороны, эти две функции скрывают большую грязную работу, необходимую для взаимодействия с Excel , и предоставляют простой в использовании интерфейс.

Во втором решении я вручную вызываю Excel COM API . Преимущество состоит в том, что мы запускаем его только один раз и срываем, когда закончим, что устраняет большие накладные расходы. Фактически, этот код выполняется менее чем за 4 секунды !:

%# 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;

Я полагаю, есть уже представлений на FEX , которые делают аналогичную вещь ...

0 голосов
/ 21 июля 2011

Я предполагаю, что вы сохранили каждый из ваших файлов Excel в формате csv с именем 'file1.csv', 'file2.csv' и т. Д.
Творческое использование команды reshape помогает изменить порядок строк.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...