CSV文件格式

 CSV即Comma Separate Values,这种文件格式经常用来作为不同程序之间的数据交互的格式。
具体文件格式

每条记录占一行
以逗号为分隔符
逗号前后的空格会被忽略
字段中包含有逗号,该字段必须用双引号括起来
字段中包含有换行符,该字段必须用双引号括起来
字段前后包含有空格,该字段必须用双引号括起来
字段中的双引号用两个双引号表示
字段中如果有双引号,该字段必须用双引号括起来
第一条记录,可以是字段名

晚上临睡之前,写了两个方法,用来把EjunGrid的内容保存到CSV格式, 算法还优待优化,我在群里搞了一个擂台赛,比试一下大家的算法功底, 看谁写的算法最精妙,代码最简洁, 优胜者将获得EjunGrid个人版一套。

 

procedure SaveGridToCSV(Grid: TZjGrid; Stream: TStream; const ABounds: TRect); overload;
  function EncodeStr(
const s: string): string;
  var
    I, k: Integer;
  begin
    I :
= Pos('"', s);
    
if I <> 0 then
    begin
      Result :
= Copy(s, 1, I) + '"';
      Inc(I);
      
while I < Length(S) do
      begin
        k :
= I;
        I :
= PosEx('"', s, I);
        
if I = 0 then
        begin
          Result :
= Result + Copy(s, k, Length(s) - k + 1);
          Break;
        end
        
else
        begin
          Result :
= Result + Copy(s, k, I - k + 1+ '"';
          Inc(I);
        end;
      end;
      Result :
= '"' + Result + '"';
    end
    
else if Pos(',', s) <> 0 then
      Result :
= '"' + s + '"'
    
else
      Result :
= s;     
  end;
var
  iRow, iCol: Integer;
  Text: 
string;
begin
  
for iRow := ABounds.Top to ABounds.Bottom do
  begin
    
for iCol := ABounds.Left to ABounds.Right do
    begin
      Text :
= EncodeStr(Grid.Cells[iCol, iRow].Text);
      
if iCol <> ABounds.Right then
        Text :
= Text + ',';
      Stream.Write(Text[
1], Length(Text));
    end;
    Text :
= #13#10;
    Stream.Write(Text[
1], Length(Text));
  end;
end;

procedure SaveGridToCSV(Grid: TZjGrid; 
const FileName: string); overload;
var
  Stream: TStream;
begin
  Stream :
= TFileStream.Create(FileName, fmCreate);
  
try
    SaveGridToCSV(Grid, Stream, Rect(Grid.FixedColCount, Grid.FixedRowCount,
      Grid.ColCount 
- 1, Grid.RowCount - 1));
  
finally
    Stream.Free;
  end;
end;

 

// 从流中加载
procedure LoadGridFromCSV(Grid: TZJGrid; Stream: TStream; DestCoord: TPoint); overload;
var
  s: 
string;
  sLen: Integer;
  newLine: Boolean;

  function FetchText(var I: Integer): 
string;
  var
    k: Integer;
    bQuote: Boolean;
  begin
    bQuote :
= False;
    newLine :
= False;
    k :
= I;
    
while k <= Length(s) do
    begin
      
if (s[k] = ',') and not bQuote then
      begin
        Result :
= Copy(s, I, k - I);
        I :
= k + 1;
        Exit;
      end
      
else if (s[k] = '"') then
      begin
        
if (k < Length(s)) and (s[k+1= '"') then
          Inc(k, 
2)
        
else
        begin
          bQuote :
= not bQuote;
          Inc(k);
        end;
      end
      
else if (s[k] = #13) and (k<Length(s)) and (s[k + 1= #10) then
      begin
        Result :
= Copy(s, I, k - I);
        newLine :
= True;
        I :
= k + 2;
        Exit;
      end
      
else
        Inc(k);
    end;
    Result :
= Copy(s, I, k - I);
  end;

var
  I: Integer;
  Text: 
string;
  iRow, iCol: Integer;
begin
  sLen :
= Stream.Size - Stream.Position;
  Grid.Clear;
  
if sLen = 0 then Exit;
  SetLength(s, sLen);
  Stream.Read(s[
1], sLen);

  I :
= 1;
  iRow :
= DestCoord.Y;
  iCol :
= DestCoord.X;
  Grid.BeginUpdate;
  
try
    
while I <= Length(s) do
    begin
      Text :
= FetchText(I);
      
if Text <> '' then
        Grid.Cells[iCol, iRow].Text :
= Text;
      
if newLine then
      begin
        Inc(iRow);
        iCol :
= DestCoord.X;
      end
      
else
        Inc(iCol);
    end;
  
finally
    Grid.EndUpdate;
  end;
end;

// 从文件中加载
procedure LoadGridFromCSV(Grid: TZJGrid; const FileName: string); overload;
var
  Stream: TFileStream;
begin
  Stream :
= TFileStream.Create(FileName, fmOpenRead);
  
try
    LoadGridFromCSV(Grid, Stream, Point(Grid.FixedColCount, Grid.FixedRowCount));
  
finally
    Stream.Free;
  end;
end;


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值