每次循环后将信息写入 Excel

发布于 2024-12-07 19:25:41 字数 232 浏览 0 评论 0原文

我有一个 6x7 矩阵(A),我正在对它进行一些操作,k=1:50(循环数)。 我知道,为了在 Excel 文件中写入单个矩阵,我需要:

xlswrite('Filename.xls', A, 'A1')

如何在每个循环之后写入信息,这样每个循环都从位置 A1+((k-1)*6+1) 开始在 Excel 中,我将 Matrix(A) 的所有结果逐一列出。

谢谢你!

I have a 6x7 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.

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眉目亦如画i 2024-12-14 19:25:41

使用 XLSWRITE 函数时,您可以避免计算每次通过指定工作表编号和范围来指定 Excel 单元格范围,其中范围仅给出起始的第一个单元格。

如果矩阵每次迭代都改变大小,则它特别有用;我们只需取出最后使用的单元格并将其移动矩阵的行数即可。

示例:

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

这将创建一个包含以下内容的 Excel 文件:

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    

请注意,每次调用 XLSWRITE 时都会建立与 Excel 的连接,然后关闭连接。这会带来很大的开销。

更好的方法是打开 Excel 一次,然后重复使用同一会话来写入所有数据,然后在完成后将其关闭。但是,您必须自己调用 Office Interop 函数。

由于我上面提到的技巧现在不起作用,我将使用 “计算 Excel 范围” 函数来计算单元格范围(FEX 还有许多其他实现)。

这是代码(重用 上一个答案):

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

事实上,我运行了两个版本 50 次迭代,并将时间与 TIC/TOC 进行了比较:

Elapsed time is 68.965848 seconds.      %# calling XLSWRITE
Elapsed time is 2.221729 seconds.       %# calling Excel COM directly

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.

Example:

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
十秒萌定你 2024-12-14 19:25:41

我认为 xlswrite 会覆盖现有文件,因此您最好收集所有数据,然后一次性写入。此外,一次性编写所有内容会更快,因为它只需要打开和关闭 Excel 一次。

但是,如果您确实想将其写在循环中,则以下内容应该可行(假设您的意思是向下):

range = sprintf('A%i:G%i', (k-1)*6+[1 6]);
xlswrite('Filename.xls', A, range);

请注意,如果 A 更改大小,这不会自动调整。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文