win7 64bit环境下读取csv,txt等到datatable

本文介绍如何在64位系统中通过安装特定驱动来读取CSV文件,并提供了一个使用Microsoft.ACE.OLEDB.12.0进行读取的C#示例。

首先要更新64位的驱动,如果系统有装32位office,就会不行。

如果是64位裸机,或者64位office的话,就没问题

需要安装

http://www.microsoft.com/ja-jp/download/details.aspx?id=13255

\Microsoft.ACE.OLEDB.12.0


例子

 public static DataTable ReadCSV(string filePath, string fileName)
        {
          
            DataTable dt = new DataTable();
            string cnStr = @"Provider=Microsoft.ACE.OLEDB.12.0;" +
                                "Data Source=" + filePath + ";" +
                                "Extended Properties=Text";
            using (OleDbConnection cn = new OleDbConnection(cnStr))
            {
                OleDbDataAdapter ad = new OleDbDataAdapter("SELECT * FROM " + fileName, cn);
                try
                {
                    ad.Fill(dt);
                }


                catch (Exception ex)
                {
                    dt = new DataTable();
                }
            }


            return dt;

classdef UnifiedDataReader % UNIFIEDDATAREADER 统一数据读取器,支持自动识别Excel/TXT文件格式 % 支持格式: .xlsx, .xls, .txt, .csv % 使用示例: % reader = UnifiedDataReader(); % data = reader.readFile(‘data.xlsx’, ‘Sheet1’, ‘A’); % Excel文件 % curves = reader.readFile(‘data.txt’, true); % 文本文件(带校验和) methods (Static) function data = readFile(filename, varargin) % READFILE 自动识别文件类型读取数据 % data = readFile(filename, ...) % % 参数说明: % Excel文件: readFile(filename, sheet, column, [Name-Value参数]) % sheet - 工作表名称/索引 % column - 列标识符(如'A'/'down_1_1')或列索引 % 'HeaderLines' - 跳过表头行数(默认0) % 'TrimBlanks' - 截断空白数据(默认true) % % 文本文件: readFile(filename, hasChecksum) % hasChecksum - 是否包含校验和(true/false) % 验证文件存在性 if ~isfile(filename) error('文件未找到: %s', filename); end % 获取文件扩展名转为小写 [~, ~, ext] = fileparts(filename); ext = lower(ext); % 根据扩展名调用相应读取方法 switch ext case {'.xlsx', '.xls', '.csv'} % Excel格式处理 if nargin < 3 error('Excel文件需要提供sheet和column参数'); end sheet = varargin{1}; column = varargin{2}; data = UnifiedDataReader.readExcel(filename, sheet, column, varargin{3:end}); case {'.txt', '.dat'} % 文本格式处理 if nargin < 2 error('文本文件需要提供hasChecksum参数'); end hasChecksum = varargin{1}; data = UnifiedDataReader.readText(filename, hasChecksum); otherwise error('不支持的文件类型: %s', ext); end end function columnData = readExcel(filename, sheet, column, varargin) % READEXCEL 读取Excel文件(静态方法) % 继承原My_readExcelColumn功能,输出数值数组 % 解析可选参数 p = inputParser; addParameter(p, 'HeaderLines', 0, @isnumeric); addParameter(p, 'TrimBlanks', true, @islogical); parse(p, varargin{:}); % 创建导入选项 opts = detectImportOptions(filename, 'Sheet', sheet); % 列标识转换 if isnumeric(column) colIndex = column; else colIndex = find(strcmpi(opts.VariableNames, column), 1); if isempty(colIndex) colIndex = UnifiedDataReader.colLetter2num(column); end end % 验证列索引 if colIndex < 1 || colIndex > numel(opts.VariableNames) error('列索引 %d 超出范围', colIndex); end % 设置导入选项 columnName = opts.VariableNames{colIndex}; opts.SelectedVariableNames = {columnName}; if p.Results.HeaderLines > 0 opts.VariableNamesRange = ''; opts.DataRange = p.Results.HeaderLines + 1; end % 读取数据 dataTable = readtable(filename, opts); columnData = table2array(dataTable(:, 1)); % 截断空白数据 if p.Results.TrimBlanks columnData = UnifiedDataReader.trimBlanks(columnData); end end function curveData = readText(filename, hasChecksum) % READTEXT 读取文本文件(静态方法) % 基于优化版的parse_serial_data % 读取文件所有行 fid = fopen(filename, 'r'); if fid == -1 error('文件打开失败: %s', filename); end lines = textscan(fid, '%s', 'Delimiter', '\n', 'WhiteSpace', ''); fclose(fid); lines = lines{1}; numLines = numel(lines); % 初始化变量 firstLineCnt = []; curveData = {}; validLines = false(numLines, 1); % 第一遍扫描:确定曲线数量 for i = 1:numLines rawLine = strtrim(lines{i}); if isempty(rawLine), continue; end tokens = regexp(rawLine, '\s+', 'split'); if numel(tokens) < 3 || ~strcmpi(tokens{1}, 'AA') || ~strcmpi(tokens{2}, '55') continue; end validLines(i) = true; if isempty(firstLineCnt) firstLineCnt = hex2dec(tokens{3}); end end % 预分配内存 maxValidLines = sum(validLines); if isempty(firstLineCnt) || maxValidLines == 0 error('未找到有效数据行'); end curveData = cell(1, firstLineCnt); for j = 1:firstLineCnt curveData{j} = zeros(maxValidLines, 1); end % 第二遍扫描:处理数据 lineCount = 0; for i = 1:numLines if ~validLines(i), continue; end rawLine = strtrim(lines{i}); tokens = regexp(rawLine, '\s+', 'split'); tokenCount = numel(tokens); currentCnt = hex2dec(tokens{3}); lineCount = lineCount + 1; % 验证数据 expectedTokens = 3 + currentCnt*2 + double(hasChecksum); if tokenCount ~= expectedTokens warning('行 %d: 预期 %d token, 实际 %d', i, expectedTokens, tokenCount); continue; end % 处理数据段 for curveIdx = 1:currentCnt byteIdx = (curveIdx-1)*2 + 4; highByte = sscanf(tokens{byteIdx}, '%2x'); lowByte = sscanf(tokens{byteIdx+1}, '%2x'); % 组合16值 value = bitor(bitshift(highByte, 8), lowByte); % 转换为有符号整数 if value > 32767 value = value - 65536; end curveData{curveIdx}(lineCount) = value; end % 校验和验证 if hasChecksum checksum = sscanf(tokens{end}, '%2x'); calcChecksum = 0; for j = 1:(numel(tokens)-1) byteVal = sscanf(tokens{j}, '%2x'); calcChecksum = mod(calcChecksum + byteVal, 256); end if checksum ~= calcChecksum warning('行 %d: 校验和错误 (计算: %d, 实际: %d)', i, calcChecksum, checksum); end end end % 修剪结果 for j = 1:length(curveData) curveData{j} = curveData{j}(1:lineCount); end end function colNum = colLetter2num(colLetters) % 列字母转数字索引 colLetters = upper(colLetters); colNum = 0; for i = 1:length(colLetters) charCode = colLetters(i); colNum = colNum * 26 + (charCode - 'A' + 1); end end function trimmedData = trimBlanks(dataArray) % 截断空白数据 (数值数组版本) nonNanIdx = ~isnan(dataArray); firstValid = find(nonNanIdx, 1, 'first'); lastValid = find(nonNanIdx, 1, 'last'); if isempty(firstValid) trimmedData = []; else trimmedData = dataArray(firstValid:lastValid); end end end end 增加功能: 在读txt文件后,对比数据线的数量和帧头包含的数据线的数量是否可以对上,同时返回读取数据线的数量
11-01
我现在有读取原始数据的两个函数,一个是My_readExcelColumn 读取excel的另一个是读取txt的TouchTxtDataRead。是不是可以把这个合成一个类,以后只要向这个类里传入文件地址。系统就会自动帮我识别文件类型,进行处理。 % % data1 = My_readExcelColumn('13MHz 110参考电容 定时时间6.5ms.xlsx', '13MHz 110参考电容 定时时间6.5ms', 'I3'); % data1 = cell2mat(data1); % writeColumnToCSV('不同频点的组合数据1.csv', data1, 1); % % data2 = My_readExcelColumn('1MHz 215参考电容 定时时间6.5ms.xlsx', '1MHz 215参考电容 定时时间6.5ms', 'I3'); % data2 = cell2mat(data2); % writeColumnToCSV('不同频点的组合数据1.csv', data2, 2); % % data3 = My_readExcelColumn('5MHz 130参考电容 定时时间6.5ms.xlsx', '5MHz 130参考电容 定时时间6.5ms', 'I3'); % data3 = cell2mat(data3); % writeColumnToCSV('不同频点的组合数据1.csv', data3, 3); % % data4 = My_readExcelColumn('5MHz 130参考电容 定时时间6.5ms.xlsx', '5MHz 130参考电容 定时时间6.5ms', 'I4'); % data4 = cell2mat(data4); % writeColumnToCSV('不同频点的组合数据1.csv', data4, 4); function columnData = My_readExcelColumn(filename, sheet, column, varargin) % READEXCELCOLUMN 读取Excel文件中指定sheet的指定列数据自动截断空白数据 % columnData = My_readExcelColumn(filename, sheet, column) % columnData = My_readExcelColumn(..., 'HeaderLines', N) 跳过N行表头 % columnData = My_readExcelColumn(..., 'TrimBlanks', true) 自动截断空白数据(默认true) % % 输入参数: % filename - Excel文件路径(字符串) % sheet - sheet名称(字符串)或sheet索引(整数) % column - 列标识(字符串如'A'、'down_1_1')或列索引(整数如1) % 'HeaderLines' - 可选参数,跳过的表头行数(默认0) % 'TrimBlanks' - 可选参数,是否截断空白数据(默认true) % % 输出参数: % columnData - 包含指定列数据的元胞数组,空白数据已被截断 % 解析可选参数 p = inputParser; addParameter(p, 'HeaderLines', 0, @isnumeric); addParameter(p, 'TrimBlanks', true, @islogical); parse(p, varargin{:}); headerLines = p.Results.HeaderLines; trimBlanks = p.Results.TrimBlanks; % 验证输入参数 if ~(ischar(filename) || isstring(filename)) error('文件名必须是字符串'); end if ~(ischar(sheet) || isnumeric(sheet) || isstring(sheet)) error('sheet参数必须是字符串或整数'); end if ~(ischar(column) || isnumeric(column) || isstring(column)) error('列标识必须是字符串或整数'); end % 转换字符串输入 if isstring(filename), filename = char(filename); end if isstring(sheet), sheet = char(sheet); end if isstring(column), column = char(column); end try % 创建导入选项 opts = detectImportOptions(filename, 'Sheet', sheet); % 统一将列标识转换为数字索引 if isnumeric(column) colIndex = column; else % 尝试将列标识转换为索引 colIndex = find(strcmpi(opts.VariableNames, column)); % 如果找不到,尝试解析为列字母 if isempty(colIndex) try colIndex = colLetter2num(column); catch error('无法识别列标识: "%s"', column); end end end % 检查列索引是否有效 if isempty(colIndex) || colIndex < 1 || colIndex > numel(opts.VariableNames) error('列索引 %d 超出范围(有效列数: %d)', colIndex, numel(opts.VariableNames)); end % 获取实际列名 columnName = opts.VariableNames{colIndex}; % 设置列选择 opts.SelectedVariableNames = {columnName}; % 设置表头处理 if headerLines > 0 opts.VariableNamesRange = ''; opts.DataRange = headerLines + 1; % 跳过指定行数 end % 读取数据 dataTable = readtable(filename, opts); % 转换为元胞数组 columnData = table2cell(dataTable); % 自动截断空白数据 if trimBlanks columnData = trimBlankCells(columnData); end catch ME error('读取Excel失败: %s', ME.message); end end %% 辅助函数:将列字母转换为数字索引 function colNum = colLetter2num(colLetters) colLetters = upper(colLetters); colNum = 0; for i = 1:length(colLetters) charCode = colLetters(i); if charCode < 'A' || charCode > 'Z' error('无效的列字母: %s', colLetters); end colNum = colNum * 26 + (charCode - 'A' + 1); end end %% 辅助函数:截断空白单元格 function trimmedData = trimBlankCells(cellData) % 查找第一个非空单元格的置 startIndex = 1; while startIndex <= numel(cellData) && isCellEmpty(cellData{startIndex}) startIndex = startIndex + 1; end % 查找最后一个非空单元格的置 endIndex = numel(cellData); while endIndex >= 1 && isCellEmpty(cellData{endIndex}) endIndex = endIndex - 1; end % 如果所有单元格都为空,返回空数组 if startIndex > endIndex trimmedData = {}; return; end % 截取非空数据部分 trimmedData = cellData(startIndex:endIndex); end %% 辅助函数:判断单元格是否为空 function isEmpty = isCellEmpty(cellContent) % 处理不同类型的数据 if ismissing(cellContent) || isempty(cellContent) || ... (ischar(cellContent) && all(isspace(cellContent))) || ... (isstring(cellContent) && (ismissing(cellContent) || strlength(cellContent) == 0)) isEmpty = true; elseif isnumeric(cellContent) && isnan(cellContent) isEmpty = true; else isEmpty = false; end end
10-18
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值