Code covered by the BSD License  

Highlights from
dat2xls

image thumbnail
from dat2xls by Fahad Al Mahmood
Copying (ASCII) data file (including headers & column names) to XLS.

dat2xls(varargin)
function dat2xls(varargin)

%DAT2XLS Copying (ASCII) data file (including headers & column names) to Excel.
%
% dat2xls  :  This program reads a (text data file) consisting of
%               headers, column titles and column data (see attached
%               data.txt).  Then it opens or creates existing excel
%               file and saves data into specified sheetname.
%
%   NOTE:   The program will automatically identify the number of
%           headerlines, columns and the column names using what so called
%           "common sense"!
% 
%  dat2xls(datfile,xlsfile,sheetname)
%  dat2xls(datfile,xlsfile)
% 
%       datfile:        Name of data file.
%       xlsfile:        Name of excel file.
%       sheetname:      sheet name (optional, default is 'Sheet1')
%                       if specified, a sheet with the specified name must
%                       be existing.
%
% Example:
% 
%      datfile = 'data.txt';
%      xlsfile = 'data.xls';
%      sheetname = 'Sheet2';
%      dat2xls(datfile,xlsfile,sheetname)
%      %dat2xls(datfile,xlsfile)             % Will write to 'Sheet1'
% 
%   Copyright 2004 Fahad Al Mahmood
%   Version: 1.0 $  $Date: 18-Feb-2004
%            1.5 $  $Date:  3-Mar-2004      % Fixed header bug + saving bug
% 
%      See also XLSWRITE, XLSHEETS


if nargin==3
    datfile = varargin{1};
    xlsfile = varargin{2};
    sheetname = varargin{3};
elseif nargin==2
    datfile = varargin{1};
    xlsfile = varargin{2};
    sheetname = 1;
end


Excel = actxserver('Excel.Application');
%set(Excel, 'Visible', 1);

% Creating a new excel workbook or Opening (xlsfile)

if exist(xlsfile,'file')==0
    % The following case if excel file does not exist (Creating New File)
    Workbook = invoke(Excel.Workbooks,'Add');
    new=1;
else
    % The following case if file does exist (Opening File)
    disp(['Opening Excel File ...(' xlsfile ')']);
    Workbook = invoke(Excel.Workbooks, 'open', [pwd filesep xlsfile]);
    new=0;
end


[data] = textread(datfile,'%s','delimiter','\n','emptyvalue',NaN);

k=1;
for i=1:length(data)
    if ~isempty(str2num(data{i}))
        m(k,:) = str2num(data{i});
        k=k+1;
    elseif ~isempty(data{i})
        header{i} = data{i};
    end
end

for ii=length(header):-1:1
    if ~isempty(header{ii})
        col_titles = header{ii};
        break;
    end
end

c=1;
rem = col_titles;
while length(rem)~=0
    [word,rem]=strtok(rem);
    if ~isspace(word)
        colnames{c} = word;
        c=c+1;
    end
end

for i=1:length(header)-1
    H{i}=header{i};
end
header=[];

if exist('H')
header = H;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Modified copy of (xlswrite)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[nr,nc] = size(m);
if nc>256
    error('Matrix is too large.  Excel only supports 256 columns');
end;

% Make the sheet active.

Sheets = Excel.ActiveWorkBook.Sheets;
target_sheet = get(Sheets, 'Item', sheetname);
invoke(target_sheet, 'Activate');

% Get a handle to the active sheet.
Activesheet = Excel.Activesheet;
%Write header
if isempty(header)
    nhr=0;
elseif iscell(header)
    nhr = length(header);       %Number header rows
    for ii=1:nhr
        ActivesheetRange = get(Activesheet,'Range',['A' num2str(ii)],['A' num2str(ii)]);
        set(ActivesheetRange, 'Value', header{ii});
    end;
else
    nhr = 1;                    %Number header rows
    ActivesheetRange = get(Activesheet,'Range','A1','A1');
    set(ActivesheetRange, 'Value', header);
end;


%Add column names
if ~isempty(colnames)
    nhr = nhr + 1;      %One extra column name
    ncolnames = length(colnames);
    for ii=1:ncolnames
        colname = xlcolumn(ii);
        cellname = [colname num2str(nhr)];
        ActivesheetRange = get(Activesheet,'Range',cellname,cellname);
        set(ActivesheetRange, 'Value', colnames{ii});
    end;
end;


% Put a MATLAB array into Excel.
FirstRow = nhr+1;           %You can change the first data row here.  I start right after the headers
LastRow = FirstRow+nr-1;
FirstCol = 'A';         %You can change the first column here
LastCol = localComputLastCol(FirstCol,nc);
ActivesheetRange = get(Activesheet,'Range',[FirstCol num2str(FirstRow)],[LastCol num2str(LastRow)]);
set(ActivesheetRange, 'Value', m);


if new
    invoke(Workbook, 'SaveAs', [pwd filesep xlsfile]);
else
    invoke(Workbook, 'Save');
end

invoke(Excel, 'Quit');
[pathstr,name,ext] = fileparts(xlsfile);

%Delete the ActiveX object
delete(Excel)


function loc = xlcolumn(column)
if isnumeric(column)
    if column>256
        error('Excel is limited to 256 columns! Enter an integer number <256');
    end
    letters = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
    count = 0;
    if column-26<=0
        loc = char(letters(column));
    else
        ocolumn = column;
        while column-26>0
            count = count + 1;
            column = column - 26;
        end
        loc = [char(letters(count)) char(letters(column))];
    end
    
else
    letters = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
    if size(column,2)==1
        loc =findstr(column,letters);
    elseif size(column,2)==2
        loc1 =findstr(column(1),letters);
        loc2 =findstr(column(2),letters);
        loc = (26 + 26*loc1)-(26-loc2);
    end
end

function LastCol = localComputLastCol(FirstCol,nc);
% Comput the name of the last column where we will place data
%Input
%  FirstCol  (string) name of first column
%  nc        total number of columns to write

%Excel's columns are named:
% A B C ... A AA AB AC AD .... BA BB BC ...
FirstColOffset = double(FirstCol) - double('A');    %Offset from column A
if nc<=26-FirstColOffset       %Easy if single letter
    %Just convert to ASCII code, add the number of needed columns, and convert back
    %to a string
    LastCol = char(double(FirstCol)+nc-1);
else
    % Fix for 52 or more columns generously provided by dragon5645995@sina.com.cn
    ng = ceil(nc/26);       %Number of groups (of 26)
    rm = rem(nc,26)+FirstColOffset;        %How many extra in this group beyond A
    if rem(nc,26)==0
        rm=26;
    end
    LastColFirstLetter = char(double('A') + ng-2);
    LastColSecondLetter = char(double('A') + rm-1);
    LastCol = [LastColFirstLetter LastColSecondLetter];
end;

Contact us at files@mathworks.com