前两天我也遇到这个问题,给你一个我写的CSV读取类
{ *********************************************************************** }
{ }
{ CSV文档读取单元 }
{ }
{ wr960204 武稀松(王锐)与 2003年7月15日 }
{ }
{ *********************************************************************** }
unit UnitReadCSV;
interface
uses
StrUtils,
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TCells = array of string;
TLinesCells = array of TCells;
const
SingleQ = '"';
do
ubleQ = '""';
comma = ',';
Enter = #$D#$A;
bEnter = #$D;
eEnter = #$A;
type
TCSVFile = class(TObject)
private
FRows: TList;
function GetRowCount: Integer;
function GetColCount: Integer;
procedure ConvertStr(LineStr: string);
procedure Clear;
function GetCells(ACol, ARow: Integer): string;
protected
property Rows: TList read FRows;
public
constructor Create();
property RowCount: Integer read GetRowCount;
//总行数
property ColCount: Integer read GetColCount;
//总列数
procedure LoadFromFile(AFileName: string);
property Cells[ACol, ARow: Integer]: string read GetCells;
//通过这里访问单元格内容
destructor Destroy;
override;
end;
implementation
{}
//转换一行
function DelQ(AStr: string): string;
//去掉引号
var
TmpStr : string;
begin
if AStr = '' then
begin
Result := AStr;
Exit;
end;
if Astr[1] = SingleQ then
//如果两边有引号就去掉
AStr := Copy(AStr, 2, Length(AStr) - 2);
Result := AnsiReplaceStr(AStr,do
ubleQ, SingleQ);
end;
procedure TCSVFile.ConvertStr(LineStr: string);
var
Posistion : Integer;
//当前字符指针
Start : Integer;
CellStr : string;
StrLength : Integer;
QCount : Integer;
NewLine : Boolean;
ColCount, RowCount: Integer;
Strs : TStrings;
I, J : Integer;
procedure AddCell();
begin
CellStr := DelQ(CellStr);
if NewLine then
begin
Strs := TStringList.Create;
Rows.Add(Strs);
Inc(RowCount);
ColCount := 1;
end
else
begin
Inc(ColCount);
end;
Strs.Add(CellStr);
NewLine := False;
Start := Posistion + 1;
end;
begin
Clear;
Start := 1;
QCount := 0;
ColCount := 0;
RowCount := 0;
StrLength := Length(LineStr);
Posistion := 0;
NewLine := True;
while Posistion < StrLengthdo
//扫描字符串
begin
Inc(Posistion);
if (LineStr[Posistion] = SingleQ) then
//如果遇到引号
Inc(QCount);
if ((LineStr[Posistion] = bEnter)) //遇到回车并且引号是双数
and ((QCount mod 2) = 0) then
begin
Inc(Posistion);
CellStr := Copy(LineStr, Start, Posistion - Start - 1);
AddCell;
Start := Posistion + 1;
NewLine := True;
Continue;
end;
if ((LineStr[Posistion] = comma)) //遇到逗号并且引号是双数
and ((QCount mod 2) = 0) then
begin
CellStr := Copy(LineStr, Start, Posistion - Start);
AddCell();
end;
if (Posistion = StrLength) then
//到了结尾
begin
CellStr := Copy(LineStr, Start, Posistion - Start + 1);
AddCell();
end;
end;
end;
procedure TCSVFile.LoadFromFile(AFileName: string);
var
lStrs : TStrings;
I : Integer;
ConverStr : string;
begin
lStrs := TStringList.Create;
try
lStrs.LoadFromFile(AFileName);
ConverStr := lStrs.Text;
ConvertStr(ConverStr);
finally
lStrs.Free;
end;
end;
{ TCSVFile }
function TCSVFile.GetColCount: Integer;
begin
if Rows.Count <> 0 then
Result := TStrings(Rows.Items[0]).Count
else
Result := 0;
end;
function TCSVFile.GetRowCount: Integer;
begin
Result := Rows.Count;
end;
procedure TCSVFile.Clear;
var
I : Integer;
begin
for I := 0 to Rows.Count - 1do
begin
TStrings(Rows.Items).Free;
end;
Rows.Clear;
end;
function TCSVFile.GetCells(ACol, ARow: Integer): string;
begin
Result := TStrings(Rows[ARow])[ACol];
end;
constructor TCSVFile.Create;
begin
FRows := TList.Create;
end;
destructor TCSVFile.Destroy;
begin
Clear;
FRows.Free;
inherited Destroy;
end;
end.