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;