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;


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值