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 elseif 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 elseif (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 elseif (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;