I have a 6×7 matrix(A) and some operation I’m doing on it for k=1:50 (number of loops).
I know that in order to write a single matrix in an excel file I need:
xlswrite('Filename.xls', A, 'A1')
How is it possible to write the information after each loop, in that way that each loop starts at position A1+((k-1)*6+1) in Excel and I have all results of Matrix(A) listed one after each other.
When using the XLSWRITE function, you can avoid having to compute Excel cell ranges each time, by specifying both sheet number and range, where range only gives the first cell to start at.
It is especially useful if the matrix changes size each iteration; we simply take the last cell used and shift it by the number of rows of the matrix.
offset = 1; for i=1:5 %# generate different size matrices each loop A = ones(randi(4),randi(4)).*i; %# insert matrix in Excel inside the 1st sheet, starting at cell specifed xlswrite('filename.xls', A, 1, sprintf('A%d',offset)); %# increment offset offset = offset + size(A,1); end
this creates an Excel file with the following content:
1 1 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5
Note that a connection is made to Excel then closed each time XLSWRITE is called. This has a significant overhead.
A better approach would be to open Excel once, and reuse the same session to write all of your data, then close it once we are done. However, you will have to call the Office Interop functions yourself.
Since the trick I mentioned above won’t work now, I will be using the “Calculate Excel Range” function to compute the cell ranges (there are many other implementations of FEX).
Here is the code (reusing some code from a previous answer):
%# output file name fName = fullfile(pwd, 'file.xls'); %# create Excel COM Server Excel = actxserver('Excel.Application'); Excel.Visible = true; %# delete existing file if exist(fName, 'file'), delete(fName); end %# create new XLS file wb = Excel.Workbooks.Add(); wb.Sheets.Item(1).Activate(); %# iterations offset = 0; for i=1:50 %# generate different size matrices each loop A = ones(randi(4),randi(4)).*i; %# calculate cell range to fit matrix (placed below previous one) cellRange = xlcalcrange('A1', offset,0, size(A,1),size(A,2)); offset = offset + size(A,1); %# insert matrix in sheet Excel.Range(cellRange).Select(); Excel.Selection.Value = num2cell(A); end %# save XLS file wb.SaveAs(fName,1); wb.Close(false); %# close Excel Excel.Quit(); Excel.delete();
In fact, I ran both version with 50 iterations, and compared timings with TIC/TOC:
Elapsed time is 68.965848 seconds. %# calling XLSWRITE Elapsed time is 2.221729 seconds. %# calling Excel COM directly
I think that
xlswrite will overwrite an existing file, so you’re better off gathering all the data, then writing it in one go. Also, writing it all in one go will be faster since it involves opening and closing Excel only once.
However, if you really want to write it in a loop, the following should work (assuming you mean going down):
range = sprintf('A%i:G%i', (k-1)*6+[1 6]); xlswrite('Filename.xls', A, range);
Note that this won’t adjust automatically if A changes size.