You've already forked lazarus-ccr
fpspreadsheet: Improve codepage handling for biff2 and biff2 files.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3924 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -321,7 +321,7 @@ begin
|
|||||||
7: WorkbookSource.FileFormat := sfOpenDocument; // Open/LibreOffice
|
7: WorkbookSource.FileFormat := sfOpenDocument; // Open/LibreOffice
|
||||||
8: WorkbookSource.FileFormat := sfCSV; // Text files
|
8: WorkbookSource.FileFormat := sfCSV; // Text files
|
||||||
end;
|
end;
|
||||||
WorkbookSource.FileName := AcFileOpen.Dialog.FileName; // this loads the file
|
WorkbookSource.FileName := UTF8ToAnsi(AcFileOpen.Dialog.FileName); // this loads the file
|
||||||
UpdateCaption;
|
UpdateCaption;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ begin
|
|||||||
6: fmt := sfCSV;
|
6: fmt := sfCSV;
|
||||||
7: fmt := sfWikiTable_WikiMedia;
|
7: fmt := sfWikiTable_WikiMedia;
|
||||||
end;
|
end;
|
||||||
WorkbookSource.SaveToSpreadsheetFile(AcFileSaveAs.Dialog.FileName, fmt);
|
WorkbookSource.SaveToSpreadsheetFile(UTF8ToAnsi(AcFileSaveAs.Dialog.FileName), fmt);
|
||||||
UpdateCaption;
|
UpdateCaption;
|
||||||
finally
|
finally
|
||||||
Screen.Cursor := crDefault;
|
Screen.Cursor := crDefault;
|
||||||
@ -401,7 +401,7 @@ begin
|
|||||||
Caption := 'demo_ctrls'
|
Caption := 'demo_ctrls'
|
||||||
else
|
else
|
||||||
Caption := Format('demo_ctrls - "%s" [%s]', [
|
Caption := Format('demo_ctrls - "%s" [%s]', [
|
||||||
WorkbookSource.Filename,
|
AnsiToUTF8(WorkbookSource.Filename),
|
||||||
GetFileFormatName(WorkbookSource.Workbook.FileFormat)
|
GetFileFormatName(WorkbookSource.Workbook.FileFormat)
|
||||||
]);
|
]);
|
||||||
end;
|
end;
|
||||||
|
@ -120,6 +120,8 @@ implementation
|
|||||||
{ TForm1 }
|
{ TForm1 }
|
||||||
|
|
||||||
procedure TForm1.BtnLoadClick(Sender: TObject);
|
procedure TForm1.BtnLoadClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
fn: ansistring;
|
||||||
begin
|
begin
|
||||||
if OpenDialog.Execute then begin
|
if OpenDialog.Execute then begin
|
||||||
WorkbookSource.AutodetectFormat := false;
|
WorkbookSource.AutodetectFormat := false;
|
||||||
@ -136,16 +138,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// There are 3 possibilities to open a file:
|
// There are 3 possibilities to open a file:
|
||||||
|
fn := UTF8ToAnsi(OpenDialog.Filename);
|
||||||
case CbLoader.ItemIndex of
|
case CbLoader.ItemIndex of
|
||||||
0: if WorkbookSource.AutodetectFormat then
|
0: if WorkbookSource.AutodetectFormat then
|
||||||
WorkbookSource.Workbook.ReadFromFile(OpenDialog.FileName)
|
WorkbookSource.Workbook.ReadFromFile(fn)
|
||||||
else
|
else
|
||||||
WorkbookSource.Workbook.ReadFromFile(OpenDialog.Filename, WorkbookSource.FileFormat);
|
WorkbookSource.Workbook.ReadFromFile(fn, WorkbookSource.FileFormat);
|
||||||
1: WorkbookSource.FileName := OpenDialog.FileName; // this loads the file
|
1: WorkbookSource.FileName := fn; // this loads the file
|
||||||
2: if WorkbookSource.AutodetectFormat then
|
2: if WorkbookSource.AutodetectFormat then
|
||||||
WorksheetGrid.LoadFromSpreadsheetFile(OpenDialog.FileName)
|
WorksheetGrid.LoadFromSpreadsheetFile(fn)
|
||||||
else
|
else
|
||||||
WorksheetGrid.LoadFromSpreadsheetFile(OpenDialog.FileName, WorkbookSource.FileFormat);
|
WorksheetGrid.LoadFromSpreadsheetFile(fn, WorkbookSource.FileFormat);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -115,21 +115,22 @@ end;
|
|||||||
// Saves sheet in grid to file, overwriting existing file
|
// Saves sheet in grid to file, overwriting existing file
|
||||||
procedure TForm1.BtnSaveClick(Sender: TObject);
|
procedure TForm1.BtnSaveClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
err: String;
|
err, fn: String;
|
||||||
begin
|
begin
|
||||||
if WorksheetGrid.Workbook = nil then
|
if WorksheetGrid.Workbook = nil then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if WorksheetGrid.Workbook.Filename <>'' then begin
|
if WorksheetGrid.Workbook.Filename <>'' then begin
|
||||||
SaveDialog.InitialDir := ExtractFileDir(WorksheetGrid.Workbook.FileName);
|
fn := AnsiToUTF8(WorksheetGrid.Workbook.Filename);
|
||||||
SaveDialog.FileName := ChangeFileExt(ExtractFileName(WorksheetGrid.Workbook.FileName), '');
|
SaveDialog.InitialDir := ExtractFileDir(fn);
|
||||||
|
SaveDialog.FileName := ChangeFileExt(ExtractFileName(fn), '');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if SaveDialog.Execute then
|
if SaveDialog.Execute then
|
||||||
begin
|
begin
|
||||||
Screen.Cursor := crHourglass;
|
Screen.Cursor := crHourglass;
|
||||||
try
|
try
|
||||||
WorksheetGrid.SaveToSpreadsheetFile(SaveDialog.FileName);
|
WorksheetGrid.SaveToSpreadsheetFile(UTF8ToAnsi(SaveDialog.FileName));
|
||||||
finally
|
finally
|
||||||
Screen.Cursor := crDefault;
|
Screen.Cursor := crDefault;
|
||||||
// Show a message in case of error(s)
|
// Show a message in case of error(s)
|
||||||
|
@ -7,7 +7,7 @@ uses
|
|||||||
cthreads,
|
cthreads,
|
||||||
{$ENDIF}{$ENDIF}
|
{$ENDIF}{$ENDIF}
|
||||||
Interfaces, // this includes the LCL widgetset
|
Interfaces, // this includes the LCL widgetset
|
||||||
Forms, mainfrm, fpsHelpers
|
Forms, mainfrm, fpsCell
|
||||||
{ you can add units after this };
|
{ you can add units after this };
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
@ -92,21 +92,23 @@ end;
|
|||||||
procedure TForm1.BtnSaveClick(Sender: TObject);
|
procedure TForm1.BtnSaveClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
err: String;
|
err: String;
|
||||||
|
fn: String;
|
||||||
begin
|
begin
|
||||||
if Grid.Workbook = nil then
|
if Grid.Workbook = nil then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if Grid.Workbook.Filename <>'' then
|
if Grid.Workbook.Filename <>'' then
|
||||||
begin
|
begin
|
||||||
SaveDialog.InitialDir := ExtractFileDir(Grid.Workbook.FileName);
|
fn := AnsiToUtf8(Grid.Workbook.Filename);
|
||||||
SaveDialog.FileName := ChangeFileExt(ExtractFileName(Grid.Workbook.FileName), '');
|
SaveDialog.InitialDir := ExtractFileDir(fn);
|
||||||
|
SaveDialog.FileName := ChangeFileExt(ExtractFileName(fn), '');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if SaveDialog.Execute then
|
if SaveDialog.Execute then
|
||||||
begin
|
begin
|
||||||
Screen.Cursor := crHourglass;
|
Screen.Cursor := crHourglass;
|
||||||
try
|
try
|
||||||
Grid.SaveToSpreadsheetFile(SaveDialog.FileName);
|
Grid.SaveToSpreadsheetFile(UTF8ToAnsi(SaveDialog.FileName));
|
||||||
finally
|
finally
|
||||||
Screen.Cursor := crDefault;
|
Screen.Cursor := crDefault;
|
||||||
// Show a message in case of error(s)
|
// Show a message in case of error(s)
|
||||||
|
@ -498,7 +498,7 @@ object MainFrm: TMainFrm
|
|||||||
BorderStyle = bsNone
|
BorderStyle = bsNone
|
||||||
ColCount = 27
|
ColCount = 27
|
||||||
MouseWheelOption = mwGrid
|
MouseWheelOption = mwGrid
|
||||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSizing, goColSizing, goThumbTracking, goDblClickAutoSize, goHeaderHotTracking, goHeaderPushedLook, goFixedColSizing]
|
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSizing, goColSizing, goThumbTracking, goDblClickAutoSize, goHeaderHotTracking, goHeaderPushedLook, goFixedColSizing, goCellHints]
|
||||||
RowCount = 101
|
RowCount = 101
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
TitleStyle = tsNative
|
TitleStyle = tsNative
|
||||||
|
@ -324,6 +324,7 @@ type
|
|||||||
procedure WorksheetGridHeaderClick(Sender: TObject; IsColumn: Boolean;
|
procedure WorksheetGridHeaderClick(Sender: TObject; IsColumn: Boolean;
|
||||||
Index: Integer);
|
Index: Integer);
|
||||||
procedure WorksheetGridSelection(Sender: TObject; aCol, aRow: Integer);
|
procedure WorksheetGridSelection(Sender: TObject; aCol, aRow: Integer);
|
||||||
|
|
||||||
private
|
private
|
||||||
FCopiedFormat: TCell;
|
FCopiedFormat: TCell;
|
||||||
procedure LoadFile(const AFileName: String);
|
procedure LoadFile(const AFileName: String);
|
||||||
@ -759,7 +760,7 @@ begin
|
|||||||
7: fmt := sfWikiTable_wikimedia;
|
7: fmt := sfWikiTable_wikimedia;
|
||||||
end;
|
end;
|
||||||
try
|
try
|
||||||
WorksheetGrid.SaveToSpreadsheetFile(SaveDialog.FileName, fmt);
|
WorksheetGrid.SaveToSpreadsheetFile(Utf8ToAnsi(SaveDialog.FileName), fmt);
|
||||||
finally
|
finally
|
||||||
Screen.Cursor := crDefault;
|
Screen.Cursor := crDefault;
|
||||||
err := WorksheetGrid.Workbook.ErrorMsg;
|
err := WorksheetGrid.Workbook.ErrorMsg;
|
||||||
@ -1006,7 +1007,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainFrm.LoadFile(const AFileName: String);
|
procedure TMainFrm.LoadFile(const AFileName: String);
|
||||||
// Loads first worksheet from file into grid
|
// Loads first worksheet from file into grid. File name is UTF8.
|
||||||
var
|
var
|
||||||
err: String;
|
err: String;
|
||||||
begin
|
begin
|
||||||
@ -1014,7 +1015,7 @@ begin
|
|||||||
Screen.Cursor := crHourglass;
|
Screen.Cursor := crHourglass;
|
||||||
try
|
try
|
||||||
try
|
try
|
||||||
WorksheetGrid.LoadFromSpreadsheetFile(UTF8ToSys(AFileName));
|
WorksheetGrid.LoadFromSpreadsheetFile(utf8ToAnsi(AFileName));
|
||||||
except
|
except
|
||||||
on E: Exception do begin
|
on E: Exception do begin
|
||||||
// In an error occurs show at least an empty valid worksheet
|
// In an error occurs show at least an empty valid worksheet
|
||||||
|
@ -1248,9 +1248,9 @@ procedure TsCellCommentAction.ExecuteTarget(Target: TObject);
|
|||||||
var
|
var
|
||||||
txt: String;
|
txt: String;
|
||||||
cellStr: String;
|
cellStr: String;
|
||||||
x, y: Integer;
|
|
||||||
R: TRect;
|
|
||||||
begin
|
begin
|
||||||
|
Unused(Target);
|
||||||
|
|
||||||
if Worksheet = nil then
|
if Worksheet = nil then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
@ -1275,6 +1275,8 @@ end;
|
|||||||
|
|
||||||
procedure TsCellCommentAction.UpdateTarget(Target: TObject);
|
procedure TsCellCommentAction.UpdateTarget(Target: TObject);
|
||||||
begin
|
begin
|
||||||
|
Unused(Target);
|
||||||
|
|
||||||
case FMode of
|
case FMode of
|
||||||
ccmNew : Enabled := (Worksheet <> nil) and (Length(GetSelection) > 0);
|
ccmNew : Enabled := (Worksheet <> nil) and (Length(GetSelection) > 0);
|
||||||
ccmEdit,
|
ccmEdit,
|
||||||
|
@ -65,7 +65,7 @@ type
|
|||||||
LineEnding: TsCSVLineEnding; // W: Specification for line ending to be written
|
LineEnding: TsCSVLineEnding; // W: Specification for line ending to be written
|
||||||
Delimiter: Char; // RW: Column delimiter
|
Delimiter: Char; // RW: Column delimiter
|
||||||
QuoteChar: Char; // RW: Character for quoting texts
|
QuoteChar: Char; // RW: Character for quoting texts
|
||||||
Encoding: String; // RW: Encoding of file
|
Encoding: String; // RW: Encoding of file (code page, such as "utf8", "cp1252" etc)
|
||||||
DetectContentType: Boolean; // R: try to convert strings to content types
|
DetectContentType: Boolean; // R: try to convert strings to content types
|
||||||
NumberFormat: String; // W: if empty write numbers like in sheet, otherwise use this format
|
NumberFormat: String; // W: if empty write numbers like in sheet, otherwise use this format
|
||||||
AutoDetectNumberFormat: Boolean; // R: automatically detects decimal/thousand separator used in numbers
|
AutoDetectNumberFormat: Boolean; // R: automatically detects decimal/thousand separator used in numbers
|
||||||
@ -202,8 +202,6 @@ end;
|
|||||||
constructor TsCSVReader.Create(AWorkbook: TsWorkbook);
|
constructor TsCSVReader.Create(AWorkbook: TsWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
FFormatSettings := CSVParams.FormatSettings;
|
|
||||||
ReplaceFormatSettings(FFormatSettings, AWorkbook.FormatSettings);
|
|
||||||
FWorksheetName := 'Sheet1'; // will be replaced by filename
|
FWorksheetName := 'Sheet1'; // will be replaced by filename
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -455,6 +453,9 @@ begin
|
|||||||
FWorkbook := AData;
|
FWorkbook := AData;
|
||||||
FWorksheet := AData.AddWorksheet(FWorksheetName, true);
|
FWorksheet := AData.AddWorksheet(FWorksheetName, true);
|
||||||
|
|
||||||
|
FFormatSettings := CSVParams.FormatSettings;
|
||||||
|
ReplaceFormatSettings(FFormatSettings, FWorkbook.FormatSettings);
|
||||||
|
|
||||||
// Create csv parser, read file and store in worksheet
|
// Create csv parser, read file and store in worksheet
|
||||||
Parser := TCSVParser.Create;
|
Parser := TCSVParser.Create;
|
||||||
try
|
try
|
||||||
|
@ -59,9 +59,9 @@ type
|
|||||||
MergeBase: PCell; // Upper left cell of a merged range
|
MergeBase: PCell; // Upper left cell of a merged range
|
||||||
Comment: String; // Comment attached to the cell
|
Comment: String; // Comment attached to the cell
|
||||||
{ Cell content }
|
{ Cell content }
|
||||||
UTF8StringValue: String; // strings cannot be part of a variant record
|
UTF8StringValue: String; // Strings cannot be part of a variant record
|
||||||
FormulaValue: String;
|
FormulaValue: String;
|
||||||
case ContentType: TCellContentType of // must be at the end of the declaration
|
case ContentType: TCellContentType of // variant part must be at the end
|
||||||
cctEmpty : (); // has no data at all
|
cctEmpty : (); // has no data at all
|
||||||
cctFormula : (); // FormulaValue is outside the variant record
|
cctFormula : (); // FormulaValue is outside the variant record
|
||||||
cctNumber : (Numbervalue: Double);
|
cctNumber : (Numbervalue: Double);
|
||||||
@ -187,9 +187,9 @@ type
|
|||||||
procedure UpdateCaches;
|
procedure UpdateCaches;
|
||||||
|
|
||||||
{ Reading of values }
|
{ Reading of values }
|
||||||
function ReadAsUTF8Text(ARow, ACol: Cardinal): ansistring; overload;
|
function ReadAsUTF8Text(ARow, ACol: Cardinal): string; overload; //ansistring; overload;
|
||||||
function ReadAsUTF8Text(ACell: PCell): ansistring; overload;
|
function ReadAsUTF8Text(ACell: PCell): string; overload; //ansistring; overload;
|
||||||
function ReadAsUTF8Text(ACell: PCell; AFormatSettings: TFormatSettings): ansistring; overload;
|
function ReadAsUTF8Text(ACell: PCell; AFormatSettings: TFormatSettings): string; overload; //ansistring; overload;
|
||||||
function ReadAsNumber(ARow, ACol: Cardinal): Double; overload;
|
function ReadAsNumber(ARow, ACol: Cardinal): Double; overload;
|
||||||
function ReadAsNumber(ACell: PCell): Double; overload;
|
function ReadAsNumber(ACell: PCell): Double; overload;
|
||||||
function ReadAsDateTime(ARow, ACol: Cardinal; out AResult: TDateTime): Boolean; overload;
|
function ReadAsDateTime(ARow, ACol: Cardinal; out AResult: TDateTime): Boolean; overload;
|
||||||
@ -555,7 +555,8 @@ type
|
|||||||
private
|
private
|
||||||
{ Internal data }
|
{ Internal data }
|
||||||
FWorksheets: TFPList;
|
FWorksheets: TFPList;
|
||||||
FEncoding: TsEncoding;
|
FCodePage: String;
|
||||||
|
// FEncoding: TsEncoding;
|
||||||
FFormat: TsSpreadsheetFormat;
|
FFormat: TsSpreadsheetFormat;
|
||||||
FBuiltinFontCount: Integer;
|
FBuiltinFontCount: Integer;
|
||||||
FPalette: array of TsColorValue;
|
FPalette: array of TsColorValue;
|
||||||
@ -694,7 +695,8 @@ type
|
|||||||
property ActiveWorksheet: TsWorksheet read FActiveWorksheet;
|
property ActiveWorksheet: TsWorksheet read FActiveWorksheet;
|
||||||
{@@ This property is only used for formats which don't support unicode
|
{@@ This property is only used for formats which don't support unicode
|
||||||
and support a single encoding for the whole document, like Excel 2 to 5 }
|
and support a single encoding for the whole document, like Excel 2 to 5 }
|
||||||
property Encoding: TsEncoding read FEncoding write FEncoding;
|
property CodePage: String read FCodePage write FCodepage;
|
||||||
|
// property Encoding: TsEncoding read FEncoding write FEncoding;
|
||||||
{@@ Retrieves error messages collected during reading/writing }
|
{@@ Retrieves error messages collected during reading/writing }
|
||||||
property ErrorMsg: String read GetErrorMsg;
|
property ErrorMsg: String read GetErrorMsg;
|
||||||
{@@ Filename of the saved workbook }
|
{@@ Filename of the saved workbook }
|
||||||
@ -2446,13 +2448,13 @@ end;
|
|||||||
Reads the contents of a cell and returns an user readable text
|
Reads the contents of a cell and returns an user readable text
|
||||||
representing the contents of the cell.
|
representing the contents of the cell.
|
||||||
|
|
||||||
The resulting ansistring is UTF-8 encoded.
|
The resulting string is UTF-8 encoded.
|
||||||
|
|
||||||
@param ARow The row of the cell
|
@param ARow The row of the cell
|
||||||
@param ACol The column of the cell
|
@param ACol The column of the cell
|
||||||
@return The text representation of the cell
|
@return The text representation of the cell
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsWorksheet.ReadAsUTF8Text(ARow, ACol: Cardinal): ansistring;
|
function TsWorksheet.ReadAsUTF8Text(ARow, ACol: Cardinal): string; //ansistring;
|
||||||
begin
|
begin
|
||||||
Result := ReadAsUTF8Text(GetCell(ARow, ACol));
|
Result := ReadAsUTF8Text(GetCell(ARow, ACol));
|
||||||
end;
|
end;
|
||||||
@ -2461,21 +2463,21 @@ end;
|
|||||||
Reads the contents of a cell and returns an user readable text
|
Reads the contents of a cell and returns an user readable text
|
||||||
representing the contents of the cell.
|
representing the contents of the cell.
|
||||||
|
|
||||||
The resulting ansistring is UTF-8 encoded.
|
The resulting string is UTF-8 encoded.
|
||||||
|
|
||||||
@param ACell Pointer to the cell
|
@param ACell Pointer to the cell
|
||||||
@return The text representation of the cell
|
@return The text representation of the cell
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsWorksheet.ReadAsUTF8Text(ACell: PCell): ansistring;
|
function TsWorksheet.ReadAsUTF8Text(ACell: PCell): string; //ansistring;
|
||||||
begin
|
begin
|
||||||
Result := ReadAsUTF8Text(ACell, FWorkbook.FormatSettings);
|
Result := ReadAsUTF8Text(ACell, FWorkbook.FormatSettings);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsWorksheet.ReadAsUTF8Text(ACell: PCell;
|
function TsWorksheet.ReadAsUTF8Text(ACell: PCell;
|
||||||
AFormatSettings: TFormatSettings): ansistring;
|
AFormatSettings: TFormatSettings): string; //ansistring;
|
||||||
|
|
||||||
function FloatToStrNoNaN(const AValue: Double;
|
function FloatToStrNoNaN(const AValue: Double;
|
||||||
ANumberFormat: TsNumberFormat; ANumberFormatStr: string): ansistring;
|
ANumberFormat: TsNumberFormat; ANumberFormatStr: string): string; //ansistring;
|
||||||
begin
|
begin
|
||||||
if IsNan(AValue) then
|
if IsNan(AValue) then
|
||||||
Result := ''
|
Result := ''
|
||||||
@ -2493,7 +2495,7 @@ function TsWorksheet.ReadAsUTF8Text(ACell: PCell;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function DateTimeToStrNoNaN(const Value: Double;
|
function DateTimeToStrNoNaN(const Value: Double;
|
||||||
ANumberFormat: TsNumberFormat; ANumberFormatStr: String): ansistring;
|
ANumberFormat: TsNumberFormat; ANumberFormatStr: String): string; //ansistring;
|
||||||
var
|
var
|
||||||
fmtp, fmtn, fmt0: String;
|
fmtp, fmtn, fmt0: String;
|
||||||
begin
|
begin
|
||||||
@ -6424,11 +6426,14 @@ end;
|
|||||||
constructor TsWorkbook.Create;
|
constructor TsWorkbook.Create;
|
||||||
var
|
var
|
||||||
fmt: TsCellFormat;
|
fmt: TsCellFormat;
|
||||||
|
cp: String;
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FWorksheets := TFPList.Create;
|
FWorksheets := TFPList.Create;
|
||||||
FLog := TStringList.Create;
|
FLog := TStringList.Create;
|
||||||
FFormat := sfExcel8;
|
FFormat := sfExcel8;
|
||||||
|
FCodePage := GetDefaultTextEncoding;
|
||||||
|
// FEncoding := seLatin1;
|
||||||
|
|
||||||
FormatSettings := UTF8FormatSettings;
|
FormatSettings := UTF8FormatSettings;
|
||||||
FormatSettings.ShortDateFormat := MakeShortDateFormat(FormatSettings.ShortDateFormat);
|
FormatSettings.ShortDateFormat := MakeShortDateFormat(FormatSettings.ShortDateFormat);
|
||||||
@ -8736,6 +8741,7 @@ end;
|
|||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsCustomSpreadWriter.WriteComment(AStream: TStream; ACell: PCell);
|
procedure TsCustomSpreadWriter.WriteComment(AStream: TStream; ACell: PCell);
|
||||||
begin
|
begin
|
||||||
|
Unused(AStream, ACell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
@ -1845,7 +1845,6 @@ var
|
|||||||
lCell: PCell;
|
lCell: PCell;
|
||||||
justif: Byte;
|
justif: Byte;
|
||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
savedBrushColor: TColor;
|
|
||||||
begin
|
begin
|
||||||
if (Worksheet = nil) then
|
if (Worksheet = nil) then
|
||||||
exit;
|
exit;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
unit fpsRPN;
|
unit fpsRPN;
|
||||||
|
|
||||||
{$ifdef fpc}
|
{$ifdef fpc}
|
||||||
{$mode delphi}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
@ -436,6 +436,7 @@ begin
|
|||||||
while item <> nil do begin
|
while item <> nil do begin
|
||||||
nextitem := item^.Next;
|
nextitem := item^.Next;
|
||||||
Result[n] := item^.FE;
|
Result[n] := item^.FE;
|
||||||
|
Result[n].StringValue := item^.FE.StringValue;
|
||||||
if AReverse then dec(n) else inc(n);
|
if AReverse then dec(n) else inc(n);
|
||||||
DisposeRPNItem(item);
|
DisposeRPNItem(item);
|
||||||
item := nextitem;
|
item := nextitem;
|
||||||
|
@ -52,6 +52,7 @@ resourcestring
|
|||||||
'text found in cell %s.';
|
'text found in cell %s.';
|
||||||
rsIndexInSSTOutOfRange = 'Index %d in SST out of range (0-%d).';
|
rsIndexInSSTOutOfRange = 'Index %d in SST out of range (0-%d).';
|
||||||
rsAmbiguousDecThouSeparator = 'Assuming usage of decimal separator in "%s".';
|
rsAmbiguousDecThouSeparator = 'Assuming usage of decimal separator in "%s".';
|
||||||
|
rsCodePageNotSupported = 'Code page "%s" is not supported. Using "cp1252" (Latin 1) instead.';
|
||||||
|
|
||||||
|
|
||||||
rsTRUE = 'TRUE'; // wp: Do we really want to translate these strings?
|
rsTRUE = 'TRUE'; // wp: Do we really want to translate these strings?
|
||||||
|
@ -48,7 +48,7 @@ const
|
|||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
(*
|
||||||
{@@ Possible encodings for a non-unicode encoded text }
|
{@@ Possible encodings for a non-unicode encoded text }
|
||||||
TsEncoding = (
|
TsEncoding = (
|
||||||
seLatin1,
|
seLatin1,
|
||||||
@ -57,8 +57,9 @@ type
|
|||||||
seGreek,
|
seGreek,
|
||||||
seTurkish,
|
seTurkish,
|
||||||
seHebrew,
|
seHebrew,
|
||||||
seArabic
|
seArabic,
|
||||||
);
|
seUTF16
|
||||||
|
); *)
|
||||||
|
|
||||||
{@@ Tokens to identify the <b>elements in an expanded formula</b>.
|
{@@ Tokens to identify the <b>elements in an expanded formula</b>.
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ type
|
|||||||
ElementKind: TFEKind;
|
ElementKind: TFEKind;
|
||||||
Row, Row2: Cardinal; // zero-based
|
Row, Row2: Cardinal; // zero-based
|
||||||
Col, Col2: Cardinal; // zero-based
|
Col, Col2: Cardinal; // zero-based
|
||||||
Param1, Param2: Word; // Extra parameters
|
// Param1, Param2: Word; // Extra parameters
|
||||||
DoubleValue: double;
|
DoubleValue: double;
|
||||||
IntValue: Word;
|
IntValue: Word;
|
||||||
StringValue: String;
|
StringValue: String;
|
||||||
@ -228,7 +229,7 @@ type
|
|||||||
|
|
||||||
Due to limitations of the text mode the characters are not rotated here.
|
Due to limitations of the text mode the characters are not rotated here.
|
||||||
There is, however, also a "stacked" variant which looks exactly like
|
There is, however, also a "stacked" variant which looks exactly like
|
||||||
the former case.
|
the 90-degrees-clockwise case.
|
||||||
}
|
}
|
||||||
TsTextRotation = (trHorizontal, rt90DegreeClockwiseRotation,
|
TsTextRotation = (trHorizontal, rt90DegreeClockwiseRotation,
|
||||||
rt90DegreeCounterClockwiseRotation, rtStacked);
|
rt90DegreeCounterClockwiseRotation, rtStacked);
|
||||||
|
@ -228,7 +228,7 @@ begin
|
|||||||
SetLength(sa, ls);
|
SetLength(sa, ls);
|
||||||
ANumbytes := ls*SizeOf(AnsiChar) + ALenBytes + 1;
|
ANumbytes := ls*SizeOf(AnsiChar) + ALenBytes + 1;
|
||||||
Move(FBuffer[ABufIndex + ALenBytes + 1], sa[1], ls*SizeOf(AnsiChar));
|
Move(FBuffer[ABufIndex + ALenBytes + 1], sa[1], ls*SizeOf(AnsiChar));
|
||||||
AString := sa;
|
AString := AnsiToUTF8(sa);
|
||||||
end else begin
|
end else begin
|
||||||
SetLength(sw, ls);
|
SetLength(sw, ls);
|
||||||
ANumBytes := ls*SizeOf(WideChar) + ALenBytes + 1;
|
ANumBytes := ls*SizeOf(WideChar) + ALenBytes + 1;
|
||||||
|
@ -381,7 +381,9 @@ var
|
|||||||
ActualDateTime: TDateTime;
|
ActualDateTime: TDateTime;
|
||||||
Row: Cardinal;
|
Row: Cardinal;
|
||||||
TempFile: string; //write xls/xml to this file and read back from it
|
TempFile: string; //write xls/xml to this file and read back from it
|
||||||
|
ErrorMargin: TDateTime;
|
||||||
begin
|
begin
|
||||||
|
ErrorMargin := 1.0/(24*60*60*1000*100); // 0.01 ms
|
||||||
TempFile:=NewTempFile;
|
TempFile:=NewTempFile;
|
||||||
{// Not needed: use workbook.writetofile with overwrite=true
|
{// Not needed: use workbook.writetofile with overwrite=true
|
||||||
if fileexists(TempFile) then
|
if fileexists(TempFile) then
|
||||||
@ -397,7 +399,8 @@ begin
|
|||||||
// Some checks inside worksheet itself
|
// Some checks inside worksheet itself
|
||||||
if not(MyWorkSheet.ReadAsDateTime(Row,0,ActualDateTime)) then
|
if not(MyWorkSheet.ReadAsDateTime(Row,0,ActualDateTime)) then
|
||||||
Fail('Failed writing date time for cell '+CellNotation(MyWorkSheet,Row));
|
Fail('Failed writing date time for cell '+CellNotation(MyWorkSheet,Row));
|
||||||
CheckEquals(SollDates[Row],ActualDateTime,'Test date/time value mismatch cell '+CellNotation(MyWorksheet,Row));
|
CheckEquals(SollDates[Row], ActualDateTime,
|
||||||
|
'Test date/time value mismatch cell '+CellNotation(MyWorksheet,Row));
|
||||||
end;
|
end;
|
||||||
MyWorkBook.WriteToFile(TempFile, AFormat, true);
|
MyWorkBook.WriteToFile(TempFile, AFormat, true);
|
||||||
finally
|
finally
|
||||||
@ -420,7 +423,8 @@ begin
|
|||||||
begin
|
begin
|
||||||
if not(MyWorkSheet.ReadAsDateTime(Row,0,ActualDateTime)) then
|
if not(MyWorkSheet.ReadAsDateTime(Row,0,ActualDateTime)) then
|
||||||
Fail('Could not read date time for cell '+CellNotation(MyWorkSheet,Row));
|
Fail('Could not read date time for cell '+CellNotation(MyWorkSheet,Row));
|
||||||
CheckEquals(SollDates[Row],ActualDateTime,'Test date/time value mismatch cell '+CellNotation(MyWorkSheet,Row));
|
CheckEquals(SollDates[Row], ActualDateTime, ErrorMargin,
|
||||||
|
'Test date/time value mismatch cell '+CellNotation(MyWorkSheet,Row));
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
MyWorkbook.Free;
|
MyWorkbook.Free;
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
<Unit1>
|
<Unit1>
|
||||||
<Filename Value="datetests.pas"/>
|
<Filename Value="datetests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="datetests"/>
|
||||||
</Unit1>
|
</Unit1>
|
||||||
<Unit2>
|
<Unit2>
|
||||||
<Filename Value="stringtests.pas"/>
|
<Filename Value="stringtests.pas"/>
|
||||||
@ -60,7 +61,6 @@
|
|||||||
<Unit4>
|
<Unit4>
|
||||||
<Filename Value="manualtests.pas"/>
|
<Filename Value="manualtests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="manualtests"/>
|
|
||||||
</Unit4>
|
</Unit4>
|
||||||
<Unit5>
|
<Unit5>
|
||||||
<Filename Value="testsutility.pas"/>
|
<Filename Value="testsutility.pas"/>
|
||||||
@ -69,21 +69,19 @@
|
|||||||
<Unit6>
|
<Unit6>
|
||||||
<Filename Value="internaltests.pas"/>
|
<Filename Value="internaltests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="internaltests"/>
|
|
||||||
</Unit6>
|
</Unit6>
|
||||||
<Unit7>
|
<Unit7>
|
||||||
<Filename Value="formattests.pas"/>
|
<Filename Value="formattests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="formattests"/>
|
|
||||||
</Unit7>
|
</Unit7>
|
||||||
<Unit8>
|
<Unit8>
|
||||||
<Filename Value="colortests.pas"/>
|
<Filename Value="colortests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="colortests"/>
|
||||||
</Unit8>
|
</Unit8>
|
||||||
<Unit9>
|
<Unit9>
|
||||||
<Filename Value="fonttests.pas"/>
|
<Filename Value="fonttests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="fonttests"/>
|
|
||||||
</Unit9>
|
</Unit9>
|
||||||
<Unit10>
|
<Unit10>
|
||||||
<Filename Value="optiontests.pas"/>
|
<Filename Value="optiontests.pas"/>
|
||||||
@ -96,15 +94,16 @@
|
|||||||
<Unit12>
|
<Unit12>
|
||||||
<Filename Value="rpnformulaunit.pas"/>
|
<Filename Value="rpnformulaunit.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="rpnFormulaUnit"/>
|
||||||
</Unit12>
|
</Unit12>
|
||||||
<Unit13>
|
<Unit13>
|
||||||
<Filename Value="formulatests.pas"/>
|
<Filename Value="formulatests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="formulatests"/>
|
||||||
</Unit13>
|
</Unit13>
|
||||||
<Unit14>
|
<Unit14>
|
||||||
<Filename Value="emptycelltests.pas"/>
|
<Filename Value="emptycelltests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="emptycelltests"/>
|
|
||||||
</Unit14>
|
</Unit14>
|
||||||
<Unit15>
|
<Unit15>
|
||||||
<Filename Value="errortests.pas"/>
|
<Filename Value="errortests.pas"/>
|
||||||
@ -121,7 +120,6 @@
|
|||||||
<Unit18>
|
<Unit18>
|
||||||
<Filename Value="celltypetests.pas"/>
|
<Filename Value="celltypetests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="celltypetests"/>
|
|
||||||
</Unit18>
|
</Unit18>
|
||||||
<Unit19>
|
<Unit19>
|
||||||
<Filename Value="sortingtests.pas"/>
|
<Filename Value="sortingtests.pas"/>
|
||||||
@ -130,7 +128,6 @@
|
|||||||
<Unit20>
|
<Unit20>
|
||||||
<Filename Value="copytests.pas"/>
|
<Filename Value="copytests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="copytests"/>
|
|
||||||
</Unit20>
|
</Unit20>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
!! DO NOT CHANGE THIS FORMULA - ITS RESULT (-9) IS HARD-CODED IN OTHER TESTS !!
|
!! DO NOT CHANGE THIS FORMULA - ITS RESULT (-9) IS HARD-CODED IN OTHER TESTS !!
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
|
||||||
|
(*
|
||||||
// Add cell values - relative addresses
|
// Add cell values - relative addresses
|
||||||
inc(Row);
|
inc(Row);
|
||||||
formula := 'B1+B2';
|
formula := 'B1+B2';
|
||||||
@ -3001,7 +3001,7 @@
|
|||||||
SetLength(sollValues, Row+1);
|
SetLength(sollValues, Row+1);
|
||||||
sollValues[Row] := StringResult('Ha');
|
sollValues[Row] := StringResult('Ha');
|
||||||
Myworksheet.WriteUTF8Text(Row, 2, sollValues[Row].ResString);
|
Myworksheet.WriteUTF8Text(Row, 2, sollValues[Row].ResString);
|
||||||
|
*)
|
||||||
// LEFT (2 parameters, utf8)
|
// LEFT (2 parameters, utf8)
|
||||||
inc(Row);
|
inc(Row);
|
||||||
formula := 'LEFT("Ändern",3)';
|
formula := 'LEFT("Ändern",3)';
|
||||||
|
@ -57,7 +57,7 @@ type
|
|||||||
|
|
||||||
TsSpreadBIFF2Reader = class(TsSpreadBIFFReader)
|
TsSpreadBIFF2Reader = class(TsSpreadBIFFReader)
|
||||||
private
|
private
|
||||||
WorkBookEncoding: TsEncoding;
|
// WorkBookEncoding: TsEncoding;
|
||||||
FFont: TsFont;
|
FFont: TsFont;
|
||||||
protected
|
protected
|
||||||
procedure CreateNumFormatList; override;
|
procedure CreateNumFormatList; override;
|
||||||
@ -110,6 +110,8 @@ type
|
|||||||
ACell: PCell); override;
|
ACell: PCell); override;
|
||||||
procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const AValue: Boolean; ACell: PCell); override;
|
const AValue: Boolean; ACell: PCell); override;
|
||||||
|
// procedure WriteCodePage(AStream: TStream; AEncoding: TsEncoding); override;
|
||||||
|
procedure WriteCodePage(AStream: TStream; ACodePage: String); override;
|
||||||
procedure WriteError(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteError(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const AValue: TsErrorValue; ACell: PCell); override;
|
const AValue: TsErrorValue; ACell: PCell); override;
|
||||||
procedure WriteLabel(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteLabel(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
@ -512,7 +514,7 @@ begin
|
|||||||
FWorkbook.RemoveAllFonts;
|
FWorkbook.RemoveAllFonts;
|
||||||
|
|
||||||
{ Store some data about the workbook that other routines need }
|
{ Store some data about the workbook that other routines need }
|
||||||
WorkBookEncoding := AData.Encoding;
|
//WorkBookEncoding := AData.Encoding;
|
||||||
|
|
||||||
BIFF2EOF := False;
|
BIFF2EOF := False;
|
||||||
|
|
||||||
@ -531,6 +533,7 @@ begin
|
|||||||
case RecordType of
|
case RecordType of
|
||||||
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
||||||
INT_EXCEL_ID_BOOLERROR : ReadBool(AStream);
|
INT_EXCEL_ID_BOOLERROR : ReadBool(AStream);
|
||||||
|
INT_EXCEL_ID_CODEPAGE : ReadCodePage(AStream);
|
||||||
INT_EXCEL_ID_NOTE : ReadComment(AStream);
|
INT_EXCEL_ID_NOTE : ReadComment(AStream);
|
||||||
INT_EXCEL_ID_FONT : ReadFont(AStream);
|
INT_EXCEL_ID_FONT : ReadFont(AStream);
|
||||||
INT_EXCEL_ID_FONTCOLOR : ReadFontColor(AStream);
|
INT_EXCEL_ID_FONTCOLOR : ReadFontColor(AStream);
|
||||||
@ -648,8 +651,8 @@ var
|
|||||||
L: Byte;
|
L: Byte;
|
||||||
ARow, ACol: Cardinal;
|
ARow, ACol: Cardinal;
|
||||||
XF: Word;
|
XF: Word;
|
||||||
AValue: ansistring;
|
ansiStr: ansistring;
|
||||||
AStrValue: UTF8String;
|
valueStr: UTF8String;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
begin
|
begin
|
||||||
{ Read entire record, starting at Row, except for string data }
|
{ Read entire record, starting at Row, except for string data }
|
||||||
@ -661,10 +664,12 @@ begin
|
|||||||
|
|
||||||
{ String with 8-bit size }
|
{ String with 8-bit size }
|
||||||
L := rec.TextLen;
|
L := rec.TextLen;
|
||||||
SetLength(AValue, L);
|
SetLength(ansiStr, L);
|
||||||
AStream.ReadBuffer(AValue[1], L);
|
AStream.ReadBuffer(ansiStr[1], L);
|
||||||
|
|
||||||
{ Save the data }
|
{ Save the data }
|
||||||
|
valueStr := ConvertEncoding(ansiStr, FCodePage, encodingUTF8);
|
||||||
|
{
|
||||||
case WorkBookEncoding of
|
case WorkBookEncoding of
|
||||||
seLatin2: AStrValue := CP1250ToUTF8(AValue);
|
seLatin2: AStrValue := CP1250ToUTF8(AValue);
|
||||||
seCyrillic: AStrValue := CP1251ToUTF8(AValue);
|
seCyrillic: AStrValue := CP1251ToUTF8(AValue);
|
||||||
@ -676,6 +681,7 @@ begin
|
|||||||
// Latin 1 is the default
|
// Latin 1 is the default
|
||||||
AStrValue := CP1252ToUTF8(AValue);
|
AStrValue := CP1252ToUTF8(AValue);
|
||||||
end;
|
end;
|
||||||
|
}
|
||||||
|
|
||||||
{ Create cell }
|
{ Create cell }
|
||||||
if FIsVirtualMode then begin
|
if FIsVirtualMode then begin
|
||||||
@ -683,7 +689,7 @@ begin
|
|||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.GetCell(ARow, ACol);
|
cell := FWorksheet.GetCell(ARow, ACol);
|
||||||
FWorksheet.WriteUTF8Text(cell, AStrValue);
|
FWorksheet.WriteUTF8Text(cell, valueStr);
|
||||||
|
|
||||||
{ Apply formatting to cell }
|
{ Apply formatting to cell }
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
@ -870,7 +876,8 @@ begin
|
|||||||
begin
|
begin
|
||||||
// The "IncompleteCell" has been identified in the sheet when reading
|
// The "IncompleteCell" has been identified in the sheet when reading
|
||||||
// the FORMULA record which precedes the String record.
|
// the FORMULA record which precedes the String record.
|
||||||
FIncompleteCell^.UTF8StringValue := AnsiToUTF8(s);
|
// FIncompleteCell^.UTF8StringValue := AnsiToUTF8(s);
|
||||||
|
FIncompleteCell^.UTF8StringValue := ConvertEncoding(s, FCodePage, encodingUTF8);
|
||||||
FIncompleteCell^.ContentType := cctUTF8String;
|
FIncompleteCell^.ContentType := cctUTF8String;
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
Workbook.OnReadCellData(Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
||||||
@ -1141,6 +1148,32 @@ begin
|
|||||||
AStream.WriteBuffer(rec, SizeOf(rec));
|
AStream.WriteBuffer(rec, SizeOf(rec));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Writes an Excel 2 CODEPAGE record
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadBIFF2Writer.WriteCodePage(AStream: TStream; ACodePage: String);
|
||||||
|
// AEncoding: TsEncoding);
|
||||||
|
begin
|
||||||
|
if ACodePage = 'cp1251' then begin
|
||||||
|
AStream.WriteWord(WordToLE(INT_EXCEL_ID_CODEPAGE));
|
||||||
|
AStream.WriteWord(WordToLE(2));
|
||||||
|
AStream.WriteWord(WordToLE(WORD_CP_1258_Latin1_BIFF2_3));
|
||||||
|
FCodePage := ACodePage;
|
||||||
|
end else
|
||||||
|
inherited;
|
||||||
|
(*
|
||||||
|
if AEncoding = seLatin1 then begin
|
||||||
|
cp := WORD_CP_1258_Latin1_BIFF2_3;
|
||||||
|
FCodePage := 'cp1252';
|
||||||
|
|
||||||
|
{ BIFF Record header }
|
||||||
|
AStream.WriteWord(WordToLE(INT_EXCEL_ID_CODEPAGE));
|
||||||
|
AStream.WriteWord(WordToLE(2));
|
||||||
|
AStream.WriteWord(WordToLE(cp));
|
||||||
|
end else
|
||||||
|
inherited; *)
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Writes an Excel 2 COLWIDTH record
|
Writes an Excel 2 COLWIDTH record
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
@ -1245,6 +1278,7 @@ begin
|
|||||||
|
|
||||||
WriteBOF(AStream);
|
WriteBOF(AStream);
|
||||||
WriteFonts(AStream);
|
WriteFonts(AStream);
|
||||||
|
WriteCodePage(AStream, Workbook.CodePage); //Encoding);
|
||||||
WriteFormatCount(AStream);
|
WriteFormatCount(AStream);
|
||||||
WriteNumFormats(AStream);
|
WriteNumFormats(AStream);
|
||||||
WriteXFRecords(AStream);
|
WriteXFRecords(AStream);
|
||||||
@ -1531,7 +1565,7 @@ var
|
|||||||
begin
|
begin
|
||||||
Unused(ANumFormatData);
|
Unused(ANumFormatData);
|
||||||
|
|
||||||
s := NumFormatList.FormatStringForWriting(AListIndex);
|
s := ConvertEncoding(NumFormatList.FormatStringForWriting(AListIndex), encodingUTF8, FCodePage);
|
||||||
len := Length(s);
|
len := Length(s);
|
||||||
|
|
||||||
{ BIFF record header }
|
{ BIFF record header }
|
||||||
|
@ -34,19 +34,15 @@ EOF
|
|||||||
The row and column numbering in BIFF files is zero-based.
|
The row and column numbering in BIFF files is zero-based.
|
||||||
|
|
||||||
Excel file format specification obtained from:
|
Excel file format specification obtained from:
|
||||||
|
|
||||||
http://sc.openoffice.org/excelfileformat.pdf
|
http://sc.openoffice.org/excelfileformat.pdf
|
||||||
|
|
||||||
Records Needed to Make a BIFF5 File Microsoft Excel Can Use obtained from:
|
Records Needed to Make a BIFF5 File Microsoft Excel Can Use obtained from:
|
||||||
|
|
||||||
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q147732&ID=KB;EN-US;Q147732&LN=EN-US&rnk=2&SD=msdn&FR=0&qry=BIFF&src=DHCS_MSPSS_msdn_SRCH&SPR=MSALL&
|
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q147732&ID=KB;EN-US;Q147732&LN=EN-US&rnk=2&SD=msdn&FR=0&qry=BIFF&src=DHCS_MSPSS_msdn_SRCH&SPR=MSALL&
|
||||||
|
|
||||||
Microsoft BIFF 5 writer example:
|
Microsoft BIFF 5 writer example:
|
||||||
|
|
||||||
http://support.microsoft.com/kb/150447/en-us
|
http://support.microsoft.com/kb/150447/en-us
|
||||||
|
|
||||||
Encoding information: ISO_8859_1 is used, to have support to
|
Encoding information: as specified fy the Encoding property of the workbook.
|
||||||
other characters, please use a format which support unicode
|
|
||||||
|
|
||||||
AUTHORS: Felipe Monteiro de Carvalho
|
AUTHORS: Felipe Monteiro de Carvalho
|
||||||
}
|
}
|
||||||
@ -101,8 +97,6 @@ type
|
|||||||
{ TsSpreadBIFF5Writer }
|
{ TsSpreadBIFF5Writer }
|
||||||
|
|
||||||
TsSpreadBIFF5Writer = class(TsSpreadBIFFWriter)
|
TsSpreadBIFF5Writer = class(TsSpreadBIFFWriter)
|
||||||
private
|
|
||||||
WorkBookEncoding: TsEncoding;
|
|
||||||
protected
|
protected
|
||||||
{ Record writing methods }
|
{ Record writing methods }
|
||||||
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
||||||
@ -353,6 +347,7 @@ begin
|
|||||||
case RecordType of
|
case RecordType of
|
||||||
INT_EXCEL_ID_BOF : ;
|
INT_EXCEL_ID_BOF : ;
|
||||||
INT_EXCEL_ID_BOUNDSHEET : ReadBoundSheet(AStream);
|
INT_EXCEL_ID_BOUNDSHEET : ReadBoundSheet(AStream);
|
||||||
|
INT_EXCEL_ID_CODEPAGE : ReadCodePage(AStream);
|
||||||
INT_EXCEL_ID_FONT : ReadFont(AStream);
|
INT_EXCEL_ID_FONT : ReadFont(AStream);
|
||||||
INT_EXCEL_ID_FORMAT : ReadFormat(AStream);
|
INT_EXCEL_ID_FORMAT : ReadFormat(AStream);
|
||||||
INT_EXCEL_ID_XF : ReadXF(AStream);
|
INT_EXCEL_ID_XF : ReadXF(AStream);
|
||||||
@ -481,7 +476,8 @@ begin
|
|||||||
|
|
||||||
SetLength(s, Len);
|
SetLength(s, Len);
|
||||||
AStream.ReadBuffer(s[1], Len*SizeOf(AnsiChar));
|
AStream.ReadBuffer(s[1], Len*SizeOf(AnsiChar));
|
||||||
sheetName := AnsiToUTF8(s);
|
// sheetName := AnsiToUTF8(s);
|
||||||
|
sheetName := ConvertEncoding(s, FCodePage, EncodingUTF8);
|
||||||
FWorksheetNames.Add(sheetName);
|
FWorksheetNames.Add(sheetName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -550,7 +546,8 @@ begin
|
|||||||
SetLength(s, Len);
|
SetLength(s, Len);
|
||||||
AStream.ReadBuffer(s[1], len);
|
AStream.ReadBuffer(s[1], len);
|
||||||
if (FIncompleteCell <> nil) and (s <> '') then begin
|
if (FIncompleteCell <> nil) and (s <> '') then begin
|
||||||
FIncompleteCell^.UTF8StringValue := AnsiToUTF8(s);
|
// FIncompleteCell^.UTF8StringValue := AnsiToUTF8(s);
|
||||||
|
FIncompletecell^.UTF8StringValue := ConvertEncoding(s, FCodePage, encodingUTF8);
|
||||||
FIncompleteCell^.ContentType := cctUTF8String;
|
FIncompleteCell^.ContentType := cctUTF8String;
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
Workbook.OnReadCellData(Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
||||||
@ -720,7 +717,6 @@ end;
|
|||||||
procedure TsSpreadBIFF5Reader.ReadFromStream(AStream: TStream; AData: TsWorkbook);
|
procedure TsSpreadBIFF5Reader.ReadFromStream(AStream: TStream; AData: TsWorkbook);
|
||||||
var
|
var
|
||||||
BIFF5EOF: Boolean;
|
BIFF5EOF: Boolean;
|
||||||
p,s: Int64;
|
|
||||||
begin
|
begin
|
||||||
{ Initializations }
|
{ Initializations }
|
||||||
|
|
||||||
@ -743,8 +739,6 @@ begin
|
|||||||
ReadWorksheet(AStream, AData);
|
ReadWorksheet(AStream, AData);
|
||||||
|
|
||||||
// Check for the end of the file
|
// Check for the end of the file
|
||||||
p := AStream.Position;
|
|
||||||
s := AStream.Size;
|
|
||||||
if AStream.Position >= AStream.Size then BIFF5EOF := True;
|
if AStream.Position >= AStream.Size then BIFF5EOF := True;
|
||||||
|
|
||||||
// Final preparations
|
// Final preparations
|
||||||
@ -818,7 +812,7 @@ begin
|
|||||||
Len := AStream.ReadByte();
|
Len := AStream.ReadByte();
|
||||||
SetLength(fontname, Len);
|
SetLength(fontname, Len);
|
||||||
AStream.ReadBuffer(fontname[1], Len);
|
AStream.ReadBuffer(fontname[1], Len);
|
||||||
font.FontName := fontname;
|
font.FontName := ConvertEncoding(fontname, FCodePage, encodingUTF8);
|
||||||
|
|
||||||
{ Add font to workbook's font list }
|
{ Add font to workbook's font list }
|
||||||
FWorkbook.AddFont(font);
|
FWorkbook.AddFont(font);
|
||||||
@ -846,7 +840,8 @@ begin
|
|||||||
AStream.ReadBuffer(fmtString[1], len);
|
AStream.ReadBuffer(fmtString[1], len);
|
||||||
|
|
||||||
// Add to the list
|
// Add to the list
|
||||||
NumFormatList.AnalyzeAndAdd(fmtIndex, AnsiToUTF8(fmtString));
|
// NumFormatList.AnalyzeAndAdd(fmtIndex, AnsiToUTF8(fmtString));
|
||||||
|
NumFormatList.AnalyzeAndAdd(fmtIndex, ConvertEncoding(fmtString, FCodePage, encodingUTF8));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF5Reader.ReadLabel(AStream: TStream);
|
procedure TsSpreadBIFF5Reader.ReadLabel(AStream: TStream);
|
||||||
@ -856,7 +851,8 @@ var
|
|||||||
ARow, ACol: Cardinal;
|
ARow, ACol: Cardinal;
|
||||||
XF: WORD;
|
XF: WORD;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
AValue: ansistring;
|
ansistr: ansistring;
|
||||||
|
valuestr: String;
|
||||||
begin
|
begin
|
||||||
rec.Row := 0; // to silence the compiler...
|
rec.Row := 0; // to silence the compiler...
|
||||||
|
|
||||||
@ -868,8 +864,8 @@ begin
|
|||||||
|
|
||||||
{ Byte String with 16-bit size }
|
{ Byte String with 16-bit size }
|
||||||
L := WordLEToN(rec.TextLen);
|
L := WordLEToN(rec.TextLen);
|
||||||
SetLength(AValue, L);
|
SetLength(ansistr, L);
|
||||||
AStream.ReadBuffer(AValue[1], L);
|
AStream.ReadBuffer(ansistr[1], L);
|
||||||
|
|
||||||
{ Create cell }
|
{ Create cell }
|
||||||
if FIsVirtualMode then begin
|
if FIsVirtualMode then begin
|
||||||
@ -879,7 +875,8 @@ begin
|
|||||||
cell := FWorksheet.GetCell(ARow, ACol);
|
cell := FWorksheet.GetCell(ARow, ACol);
|
||||||
|
|
||||||
{ Save the data }
|
{ Save the data }
|
||||||
FWorksheet.WriteUTF8Text(cell, ISO_8859_1ToUTF8(AValue));
|
valueStr := ConvertEncoding(ansistr, FCodePage, encodingUTF8);
|
||||||
|
FWorksheet.WriteUTF8Text(cell, valueStr); //ISO_8859_1ToUTF8(ansistr));
|
||||||
|
|
||||||
{ Add attributes }
|
{ Add attributes }
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
@ -939,14 +936,11 @@ var
|
|||||||
i, len: Integer;
|
i, len: Integer;
|
||||||
pane: Byte;
|
pane: Byte;
|
||||||
begin
|
begin
|
||||||
{ Store some data about the workbook that other routines need }
|
|
||||||
WorkBookEncoding := Workbook.Encoding;
|
|
||||||
|
|
||||||
{ Write workbook globals }
|
{ Write workbook globals }
|
||||||
|
|
||||||
WriteBOF(AStream, INT_BOF_WORKBOOK_GLOBALS);
|
WriteBOF(AStream, INT_BOF_WORKBOOK_GLOBALS);
|
||||||
|
|
||||||
WriteCodepage(AStream, WorkBookEncoding);
|
WriteCodepage(AStream, Workbook.CodePage); //WorkBook.Encoding);
|
||||||
WriteWindow1(AStream);
|
WriteWindow1(AStream);
|
||||||
WriteFonts(AStream);
|
WriteFonts(AStream);
|
||||||
WriteNumFormats(AStream);
|
WriteNumFormats(AStream);
|
||||||
@ -1042,11 +1036,14 @@ end;
|
|||||||
function TsSpreadBIFF5Writer.WriteBoundsheet(AStream: TStream; ASheetName: string): Int64;
|
function TsSpreadBIFF5Writer.WriteBoundsheet(AStream: TStream; ASheetName: string): Int64;
|
||||||
var
|
var
|
||||||
Len: Byte;
|
Len: Byte;
|
||||||
LatinSheetName: string;
|
xlsSheetName: ansistring;
|
||||||
begin
|
begin
|
||||||
|
xlsSheetName := ConvertEncoding(ASheetName, encodingUTF8, FCodePage);
|
||||||
|
Len := Length(xlsSheetName);
|
||||||
|
{
|
||||||
LatinSheetName := UTF8ToISO_8859_1(ASheetName);
|
LatinSheetName := UTF8ToISO_8859_1(ASheetName);
|
||||||
Len := Length(LatinSheetName);
|
Len := Length(LatinSheetName);
|
||||||
|
}
|
||||||
{ BIFF Record header }
|
{ BIFF Record header }
|
||||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_BOUNDSHEET));
|
AStream.WriteWord(WordToLE(INT_EXCEL_ID_BOUNDSHEET));
|
||||||
AStream.WriteWord(WordToLE(6 + 1 + Len));
|
AStream.WriteWord(WordToLE(6 + 1 + Len));
|
||||||
@ -1064,7 +1061,8 @@ begin
|
|||||||
|
|
||||||
{ Sheet name: Byte string, 8-bit length }
|
{ Sheet name: Byte string, 8-bit length }
|
||||||
AStream.WriteByte(Len);
|
AStream.WriteByte(Len);
|
||||||
AStream.WriteBuffer(LatinSheetName[1], Len);
|
// AStream.WriteBuffer(LatinSheetName[1], Len);
|
||||||
|
AStream.WriteBuffer(xlsSheetName[1], Len);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -1204,15 +1202,18 @@ type
|
|||||||
end;
|
end;
|
||||||
var
|
var
|
||||||
len: Integer;
|
len: Integer;
|
||||||
s: ansistring;
|
fmtStr: String;
|
||||||
|
ansiFmtStr: ansiString;
|
||||||
rec: TNumFormatRecord;
|
rec: TNumFormatRecord;
|
||||||
buf: array of byte;
|
buf: array of byte;
|
||||||
begin
|
begin
|
||||||
if (ANumFormatData = nil) or (ANumFormatData.FormatString = '') then
|
if (ANumFormatData = nil) or (ANumFormatData.FormatString = '') then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
s := UTF8ToAnsi(NumFormatList.FormatStringForWriting(AListIndex));
|
// s := UTF8ToAnsi(NumFormatList.FormatStringForWriting(AListIndex));
|
||||||
len := Length(s);
|
fmtStr := NumFormatList.FormatStringForWriting(AListIndex);
|
||||||
|
ansiFmtStr := ConvertEncoding(fmtStr, encodingUTF8, FCodePage);
|
||||||
|
len := Length(ansiFmtStr);
|
||||||
|
|
||||||
{ BIFF record header }
|
{ BIFF record header }
|
||||||
rec.RecordID := WordToLE(INT_EXCEL_ID_FORMAT);
|
rec.RecordID := WordToLE(INT_EXCEL_ID_FORMAT);
|
||||||
@ -1227,7 +1228,7 @@ begin
|
|||||||
{ Copy the format string characters into a buffer immediately after rec }
|
{ Copy the format string characters into a buffer immediately after rec }
|
||||||
SetLength(buf, SizeOf(rec) + SizeOf(ansiChar)*len);
|
SetLength(buf, SizeOf(rec) + SizeOf(ansiChar)*len);
|
||||||
Move(rec, buf[0], SizeOf(rec));
|
Move(rec, buf[0], SizeOf(rec));
|
||||||
Move(s[1], buf[SizeOf(rec)], len*SizeOf(ansiChar));
|
Move(ansiFmtStr[1], buf[SizeOf(rec)], len*SizeOf(ansiChar));
|
||||||
|
|
||||||
{ Write out }
|
{ Write out }
|
||||||
AStream.WriteBuffer(buf[0], SizeOf(Rec) + SizeOf(ansiChar)*len);
|
AStream.WriteBuffer(buf[0], SizeOf(Rec) + SizeOf(ansiChar)*len);
|
||||||
@ -1284,6 +1285,8 @@ begin
|
|||||||
if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
|
if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
ansiValue := ConvertEncoding(AValue, encodingUTF8, FCodePage);
|
||||||
|
{
|
||||||
case WorkBookEncoding of
|
case WorkBookEncoding of
|
||||||
seLatin2: AnsiValue := UTF8ToCP1250(AValue);
|
seLatin2: AnsiValue := UTF8ToCP1250(AValue);
|
||||||
seCyrillic: AnsiValue := UTF8ToCP1251(AValue);
|
seCyrillic: AnsiValue := UTF8ToCP1251(AValue);
|
||||||
@ -1295,6 +1298,7 @@ begin
|
|||||||
// Latin 1 is the default
|
// Latin 1 is the default
|
||||||
AnsiValue := UTF8ToCP1252(AValue);
|
AnsiValue := UTF8ToCP1252(AValue);
|
||||||
end;
|
end;
|
||||||
|
}
|
||||||
|
|
||||||
if AnsiValue = '' then begin
|
if AnsiValue = '' then begin
|
||||||
// Bad formatted UTF8String (maybe ANSI?)
|
// Bad formatted UTF8String (maybe ANSI?)
|
||||||
@ -1354,7 +1358,8 @@ var
|
|||||||
s: ansistring;
|
s: ansistring;
|
||||||
len: Integer;
|
len: Integer;
|
||||||
begin
|
begin
|
||||||
s := UTF8ToAnsi(AString);
|
// s := UTF8ToAnsi(AString);
|
||||||
|
s := ConvertEncoding(AString, encodingUTF8, FCodePage);
|
||||||
len := Length(s);
|
len := Length(s);
|
||||||
|
|
||||||
{ BIFF Record header }
|
{ BIFF Record header }
|
||||||
|
@ -78,7 +78,7 @@ type
|
|||||||
procedure ReadWorkbookGlobals(AStream: TStream; AData: TsWorkbook);
|
procedure ReadWorkbookGlobals(AStream: TStream; AData: TsWorkbook);
|
||||||
procedure ReadWorksheet(AStream: TStream; AData: TsWorkbook);
|
procedure ReadWorksheet(AStream: TStream; AData: TsWorkbook);
|
||||||
procedure ReadBoundsheet(AStream: TStream);
|
procedure ReadBoundsheet(AStream: TStream);
|
||||||
function ReadString(const AStream: TStream; const ALength: WORD): UTF8String;
|
function ReadString(const AStream: TStream; const ALength: WORD): String;
|
||||||
protected
|
protected
|
||||||
procedure ReadFont(const AStream: TStream);
|
procedure ReadFont(const AStream: TStream);
|
||||||
procedure ReadFormat(AStream: TStream); override;
|
procedure ReadFormat(AStream: TStream); override;
|
||||||
@ -219,7 +219,7 @@ var
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Math, fpsStrings, fpsStreams, fpsExprParser;
|
Math, lconvencoding, fpsStrings, fpsStreams, fpsExprParser;
|
||||||
|
|
||||||
const
|
const
|
||||||
{ Excel record IDs }
|
{ Excel record IDs }
|
||||||
@ -349,7 +349,7 @@ var
|
|||||||
lLen: SizeInt;
|
lLen: SizeInt;
|
||||||
RecordType: WORD;
|
RecordType: WORD;
|
||||||
RecordSize: WORD;
|
RecordSize: WORD;
|
||||||
C: char;
|
C: WideChar;
|
||||||
begin
|
begin
|
||||||
StringFlags:=AStream.ReadByte;
|
StringFlags:=AStream.ReadByte;
|
||||||
Dec(PendingRecordSize);
|
Dec(PendingRecordSize);
|
||||||
@ -376,17 +376,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
Result := WideStringLEToN(Result);
|
Result := WideStringLEToN(Result);
|
||||||
end else begin
|
end else begin
|
||||||
//String is 1 byte per char, this is UTF-16 with the high byte ommited because it is zero
|
// String is 1 byte per char, this is UTF-16 with the high byte ommited
|
||||||
//so decompress and then convert
|
// because it is zero, so decompress and then convert
|
||||||
lLen := ALength;
|
lLen := ALength;
|
||||||
SetLength(DecomprStrValue, lLen);
|
SetLength(DecomprStrValue, lLen);
|
||||||
for i := 1 to lLen do
|
for i := 1 to lLen do
|
||||||
begin
|
begin
|
||||||
C:=WideChar(AStream.ReadByte());
|
C := WideChar(AStream.ReadByte); // Read 1 byte, but put it into a 2-byte char
|
||||||
DecomprStrValue[i] := C;
|
DecomprStrValue[i] := C;
|
||||||
Dec(PendingRecordSize);
|
Dec(PendingRecordSize);
|
||||||
if (PendingRecordSize <= 0) and (i < lLen) then begin
|
if (PendingRecordSize <= 0) and (i < lLen) then begin
|
||||||
//A CONTINUE may happend here
|
//A CONTINUE may have happened here
|
||||||
RecordType := WordLEToN(AStream.ReadWord);
|
RecordType := WordLEToN(AStream.ReadWord);
|
||||||
RecordSize := WordLEToN(AStream.ReadWord);
|
RecordSize := WordLEToN(AStream.ReadWord);
|
||||||
if RecordType <> INT_EXCEL_ID_CONTINUE then begin
|
if RecordType <> INT_EXCEL_ID_CONTINUE then begin
|
||||||
@ -398,7 +398,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result := DecomprStrValue;
|
Result := DecomprStrValue;
|
||||||
end;
|
end;
|
||||||
if StringFlags and 8 = 8 then begin
|
if StringFlags and 8 = 8 then begin
|
||||||
@ -572,7 +571,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSpreadBIFF8Reader.ReadString(const AStream: TStream;
|
function TsSpreadBIFF8Reader.ReadString(const AStream: TStream;
|
||||||
const ALength: WORD): UTF8String;
|
const ALength: WORD): String;
|
||||||
begin
|
begin
|
||||||
Result := UTF16ToUTF8(ReadWideString(AStream, ALength));
|
Result := UTF16ToUTF8(ReadWideString(AStream, ALength));
|
||||||
end;
|
end;
|
||||||
@ -618,14 +617,12 @@ begin
|
|||||||
BIFF8EOF := False;
|
BIFF8EOF := False;
|
||||||
|
|
||||||
{ Read workbook globals }
|
{ Read workbook globals }
|
||||||
|
|
||||||
ReadWorkbookGlobals(AStream, AData);
|
ReadWorkbookGlobals(AStream, AData);
|
||||||
|
|
||||||
// Check for the end of the file
|
// Check for the end of the file
|
||||||
if AStream.Position >= AStream.Size then BIFF8EOF := True;
|
if AStream.Position >= AStream.Size then BIFF8EOF := True;
|
||||||
|
|
||||||
{ Now read all worksheets }
|
{ Now read all worksheets }
|
||||||
|
|
||||||
while (not BIFF8EOF) do
|
while (not BIFF8EOF) do
|
||||||
begin
|
begin
|
||||||
//Safe to not read beyond assigned worksheet names.
|
//Safe to not read beyond assigned worksheet names.
|
||||||
@ -647,9 +644,7 @@ begin
|
|||||||
FWorkbook.UsePalette(@PALETTE_BIFF8, Length(PALETTE_BIFF8));
|
FWorkbook.UsePalette(@PALETTE_BIFF8, Length(PALETTE_BIFF8));
|
||||||
|
|
||||||
{ Finalizations }
|
{ Finalizations }
|
||||||
|
|
||||||
FWorksheetNames.Free;
|
FWorksheetNames.Free;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF8Reader.ReadLabel(AStream: TStream);
|
procedure TsSpreadBIFF8Reader.ReadLabel(AStream: TStream);
|
||||||
@ -956,20 +951,22 @@ end;
|
|||||||
|
|
||||||
{ Helper function for reading a string with 8-bit length. }
|
{ Helper function for reading a string with 8-bit length. }
|
||||||
function TsSpreadBIFF8Reader.ReadString_8bitLen(AStream: TStream): String;
|
function TsSpreadBIFF8Reader.ReadString_8bitLen(AStream: TStream): String;
|
||||||
|
const
|
||||||
|
HAS_8BITLEN = true;
|
||||||
var
|
var
|
||||||
s: widestring;
|
wideStr: widestring;
|
||||||
begin
|
begin
|
||||||
s := ReadWideString(AStream, true);
|
wideStr := ReadWideString(AStream, HAS_8BITLEN);
|
||||||
Result := UTF8Encode(s);
|
Result := UTF8Encode(wideStr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF8Reader.ReadStringRecord(AStream: TStream);
|
procedure TsSpreadBIFF8Reader.ReadStringRecord(AStream: TStream);
|
||||||
var
|
var
|
||||||
s: String;
|
wideStr: WideString;
|
||||||
begin
|
begin
|
||||||
s := ReadWideString(AStream, false);
|
wideStr := ReadWideString(AStream, false);
|
||||||
if (FIncompleteCell <> nil) and (s <> '') then begin
|
if (FIncompleteCell <> nil) and (wideStr <> '') then begin
|
||||||
FIncompleteCell^.UTF8StringValue := UTF8Encode(s);
|
FIncompleteCell^.UTF8StringValue := UTF8Encode(wideStr);
|
||||||
FIncompleteCell^.ContentType := cctUTF8String;
|
FIncompleteCell^.ContentType := cctUTF8String;
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
Workbook.OnReadCellData(Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
||||||
@ -984,14 +981,12 @@ procedure TsSpreadBIFF8Reader.ReadXF(const AStream: TStream);
|
|||||||
begin
|
begin
|
||||||
case dw of
|
case dw of
|
||||||
$01..$07: result := TsLineStyle(dw-1);
|
$01..$07: result := TsLineStyle(dw-1);
|
||||||
// $07: Result := lsDotted;
|
|
||||||
else Result := lsDashed;
|
else Result := lsDashed;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
var
|
var
|
||||||
rec: TBIFF8_XFRecord;
|
rec: TBIFF8_XFRecord;
|
||||||
fmt: TsCellFormat;
|
fmt: TsCellFormat;
|
||||||
// xf: TXFRecord;
|
|
||||||
b: Byte;
|
b: Byte;
|
||||||
dw: DWord;
|
dw: DWord;
|
||||||
fill: Integer;
|
fill: Integer;
|
||||||
@ -1271,9 +1266,8 @@ var
|
|||||||
pane: Byte;
|
pane: Byte;
|
||||||
begin
|
begin
|
||||||
{ Write workbook globals }
|
{ Write workbook globals }
|
||||||
|
|
||||||
WriteBOF(AStream, INT_BOF_WORKBOOK_GLOBALS);
|
WriteBOF(AStream, INT_BOF_WORKBOOK_GLOBALS);
|
||||||
|
WriteCodePage(AStream, 'ucs2le'); //seUTF16);
|
||||||
WriteWindow1(AStream);
|
WriteWindow1(AStream);
|
||||||
WriteFonts(AStream);
|
WriteFonts(AStream);
|
||||||
WriteNumFormats(AStream);
|
WriteNumFormats(AStream);
|
||||||
@ -1293,7 +1287,6 @@ begin
|
|||||||
WriteEOF(AStream);
|
WriteEOF(AStream);
|
||||||
|
|
||||||
{ Write each worksheet }
|
{ Write each worksheet }
|
||||||
|
|
||||||
for i := 0 to Workbook.GetWorksheetCount - 1 do
|
for i := 0 to Workbook.GetWorksheetCount - 1 do
|
||||||
begin
|
begin
|
||||||
FWorksheet := Workbook.GetWorksheetByIndex(i);
|
FWorksheet := Workbook.GetWorksheetByIndex(i);
|
||||||
@ -1483,7 +1476,7 @@ begin
|
|||||||
if AFont.Size <= 0.0 then
|
if AFont.Size <= 0.0 then
|
||||||
raise Exception.Create('Font size not specified.');
|
raise Exception.Create('Font size not specified.');
|
||||||
|
|
||||||
WideFontName := AFont.FontName;
|
WideFontName := UTF8Decode(AFont.FontName);
|
||||||
Len := Length(WideFontName);
|
Len := Length(WideFontName);
|
||||||
|
|
||||||
{ BIFF Record header }
|
{ BIFF Record header }
|
||||||
|
@ -4,20 +4,13 @@ unit xlscommon;
|
|||||||
OpenOffice Microsoft Excel File Format document }
|
OpenOffice Microsoft Excel File Format document }
|
||||||
|
|
||||||
{$ifdef fpc}
|
{$ifdef fpc}
|
||||||
{$mode delphi}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, DateUtils,
|
Classes, SysUtils, DateUtils,
|
||||||
(*
|
|
||||||
{$ifdef USE_NEW_OLE}
|
|
||||||
fpolebasic,
|
|
||||||
{$else}
|
|
||||||
fpolestorage,
|
|
||||||
{$endif}
|
|
||||||
*)
|
|
||||||
fpstypes, fpspreadsheet, fpsutils, lconvencoding;
|
fpstypes, fpspreadsheet, fpsutils, lconvencoding;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -73,6 +66,11 @@ const
|
|||||||
|
|
||||||
{ CODEPAGE record constants }
|
{ CODEPAGE record constants }
|
||||||
WORD_ASCII = 367;
|
WORD_ASCII = 367;
|
||||||
|
WORD_CP_437_DOS_US = 437;
|
||||||
|
WORD_CP_850_DOS_Latin1 = 850;
|
||||||
|
WORD_CP_852_DOS_Latin2 = 852;
|
||||||
|
WORD_CP_866_DOS_Cyrillic = 866;
|
||||||
|
WORD_CP_874_Thai = 874;
|
||||||
WORD_UTF_16 = 1200; // BIFF 8
|
WORD_UTF_16 = 1200; // BIFF 8
|
||||||
WORD_CP_1250_Latin2 = 1250;
|
WORD_CP_1250_Latin2 = 1250;
|
||||||
WORD_CP_1251_Cyrillic = 1251;
|
WORD_CP_1251_Cyrillic = 1251;
|
||||||
@ -304,6 +302,7 @@ type
|
|||||||
FDateMode: TDateMode;
|
FDateMode: TDateMode;
|
||||||
FLastRow: Cardinal;
|
FLastRow: Cardinal;
|
||||||
FLastCol: Cardinal;
|
FLastCol: Cardinal;
|
||||||
|
FCodePage: String; // in a format prepared for lconvencoding.ConvertEncoding
|
||||||
procedure CreateNumFormatList; override;
|
procedure CreateNumFormatList; override;
|
||||||
function FindXFIndex(ACell: PCell): Integer; virtual;
|
function FindXFIndex(ACell: PCell): Integer; virtual;
|
||||||
function FixColor(AColor: TsColor): TsColor; override;
|
function FixColor(AColor: TsColor): TsColor; override;
|
||||||
@ -321,7 +320,7 @@ type
|
|||||||
procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const AValue: Boolean; ACell: PCell); override;
|
const AValue: Boolean; ACell: PCell); override;
|
||||||
// Writes out used codepage for character encoding
|
// Writes out used codepage for character encoding
|
||||||
procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding);
|
procedure WriteCodePage(AStream: TStream; ACodePage: String); virtual;
|
||||||
// Writes out column info(s)
|
// Writes out column info(s)
|
||||||
procedure WriteColInfo(AStream: TStream; ACol: PCol);
|
procedure WriteColInfo(AStream: TStream; ACol: PCol);
|
||||||
procedure WriteColInfos(AStream: TStream; ASheet: TsWorksheet);
|
procedure WriteColInfos(AStream: TStream; ASheet: TsWorksheet);
|
||||||
@ -403,7 +402,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
AVL_Tree, Math, Variants,
|
AVL_Tree, Math, Variants,
|
||||||
{%H-}fpspatches, xlsConst, fpsNumFormatParser, fpsrpn, fpsExprParser;
|
{%H-}fpspatches, fpsStrings, xlsConst, fpsNumFormatParser, fpsrpn, fpsExprParser;
|
||||||
|
|
||||||
const
|
const
|
||||||
{ Helper table for rpn formulas:
|
{ Helper table for rpn formulas:
|
||||||
@ -828,18 +827,12 @@ begin
|
|||||||
|
|
||||||
case lCodePage of
|
case lCodePage of
|
||||||
// 016FH = 367 = ASCII
|
// 016FH = 367 = ASCII
|
||||||
// 01B5H = 437 = IBM PC CP-437 (US)
|
WORD_CP_437_DOS_US: FCodePage := 'cp437'; // IBM PC CP-437 (US)
|
||||||
//02D0H = 720 = IBM PC CP-720 (OEM Arabic)
|
//02D0H = 720 = IBM PC CP-720 (OEM Arabic)
|
||||||
//02E1H = 737 = IBM PC CP-737 (Greek)
|
//02E1H = 737 = IBM PC CP-737 (Greek)
|
||||||
//0307H = 775 = IBM PC CP-775 (Baltic)
|
//0307H = 775 = IBM PC CP-775 (Baltic)
|
||||||
//0352H = 850 = IBM PC CP-850 (Latin I)
|
WORD_CP_850_DOS_Latin1: FCodepage := 'cp850'; // IBM PC CP-850 (Latin I)
|
||||||
$0352: FCodepage := 'cp850';
|
WORD_CP_852_DOS_Latin2: FCodepage := 'cp852'; // IBM PC CP-852 (Latin II (Central European))
|
||||||
//0354H = 852 = IBM PC CP-852 (Latin II (Central European))
|
|
||||||
$0354: FCodepage := 'cp852';
|
|
||||||
//0357H = 855 = IBM PC CP-855 (Cyrillic)
|
|
||||||
$0357: FCodepage := 'cp855';
|
|
||||||
//0359H = 857 = IBM PC CP-857 (Turkish)
|
|
||||||
$0359: FCodepage := 'cp857';
|
|
||||||
//035AH = 858 = IBM PC CP-858 (Multilingual Latin I with Euro)
|
//035AH = 858 = IBM PC CP-858 (Multilingual Latin I with Euro)
|
||||||
//035CH = 860 = IBM PC CP-860 (Portuguese)
|
//035CH = 860 = IBM PC CP-860 (Portuguese)
|
||||||
//035DH = 861 = IBM PC CP-861 (Icelandic)
|
//035DH = 861 = IBM PC CP-861 (Icelandic)
|
||||||
@ -847,29 +840,27 @@ begin
|
|||||||
//035FH = 863 = IBM PC CP-863 (Canadian (French))
|
//035FH = 863 = IBM PC CP-863 (Canadian (French))
|
||||||
//0360H = 864 = IBM PC CP-864 (Arabic)
|
//0360H = 864 = IBM PC CP-864 (Arabic)
|
||||||
//0361H = 865 = IBM PC CP-865 (Nordic)
|
//0361H = 865 = IBM PC CP-865 (Nordic)
|
||||||
//0362H = 866 = IBM PC CP-866 (Cyrillic (Russian))
|
WORD_CP_866_DOS_Cyrillic: FCodePage := 'cp866'; // IBM PC CP-866 (Cyrillic Russian)
|
||||||
//0365H = 869 = IBM PC CP-869 (Greek (Modern))
|
//0365H = 869 = IBM PC CP-869 (Greek (Modern))
|
||||||
//036AH = 874 = Windows CP-874 (Thai)
|
WORD_CP_874_Thai: FCodePage := 'cp874'; // 874 = Windows CP-874 (Thai)
|
||||||
//03A4H = 932 = Windows CP-932 (Japanese Shift-JIS)
|
//03A4H = 932 = Windows CP-932 (Japanese Shift-JIS)
|
||||||
//03A8H = 936 = Windows CP-936 (Chinese Simplified GBK)
|
//03A8H = 936 = Windows CP-936 (Chinese Simplified GBK)
|
||||||
//03B5H = 949 = Windows CP-949 (Korean (Wansung))
|
//03B5H = 949 = Windows CP-949 (Korean (Wansung))
|
||||||
//03B6H = 950 = Windows CP-950 (Chinese Traditional BIG5)
|
//03B6H = 950 = Windows CP-950 (Chinese Traditional BIG5)
|
||||||
//04B0H = 1200 = UTF-16 (BIFF8)
|
WORD_UTF_16 : FCodePage := 'ucs2le'; // UTF-16 (BIFF8)
|
||||||
$04B0: FCodepage := 'utf-16';
|
WORD_CP_1250_Latin2: FCodepage := 'cp1250'; // Windows CP-1250 (Latin II) (Central European)
|
||||||
//04E2H = 1250 = Windows CP-1250 (Latin II) (Central European)
|
WORD_CP_1251_Cyrillic: FCodePage := 'cp1251'; // Windows CP-1251 (Cyrillic)
|
||||||
//04E3H = 1251 = Windows CP-1251 (Cyrillic)
|
WORD_CP_1252_Latin1: FCodePage := 'cp1252'; // Windows CP-1252 (Latin I) (BIFF4-BIFF5)
|
||||||
//04E4H = 1252 = Windows CP-1252 (Latin I) (BIFF4-BIFF5)
|
WORD_CP_1253_Greek: FCodePage := 'cp1253'; // Windows CP-1253 (Greek)
|
||||||
//04E5H = 1253 = Windows CP-1253 (Greek)
|
WORD_CP_1254_Turkish: FCodepage := 'cp1254'; // Windows CP-1254 (Turkish)
|
||||||
//04E6H = 1254 = Windows CP-1254 (Turkish)
|
WORD_CP_1255_Hebrew: FCodePage := 'cp1255'; // Windows CP-1255 (Hebrew)
|
||||||
$04E6: FCodepage := 'cp1254';
|
WORD_CP_1256_Arabic: FCodePage := 'cp1256'; // Windows CP-1256 (Arabic)
|
||||||
//04E7H = 1255 = Windows CP-1255 (Hebrew)
|
WORD_CP_1257_Baltic: FCodePage := 'cp1257'; // Windows CP-1257 (Baltic)
|
||||||
//04E8H = 1256 = Windows CP-1256 (Arabic)
|
WORD_CP_1258_Vietnamese: FCodePage := 'cp1258'; // Windows CP-1258 (Vietnamese)
|
||||||
//04E9H = 1257 = Windows CP-1257 (Baltic)
|
|
||||||
//04EAH = 1258 = Windows CP-1258 (Vietnamese)
|
|
||||||
//0551H = 1361 = Windows CP-1361 (Korean (Johab))
|
//0551H = 1361 = Windows CP-1361 (Korean (Johab))
|
||||||
//2710H = 10000 = Apple Roman
|
//2710H = 10000 = Apple Roman
|
||||||
//8000H = 32768 = Apple Roman
|
//8000H = 32768 = Apple Roman
|
||||||
//8001H = 32769 = Windows CP-1252 (Latin I) (BIFF2-BIFF3)
|
WORD_CP_1258_Latin1_BIFF2_3: FCodePage := 'cp1252'; // Windows CP-1252 (Latin I) (BIFF2-BIFF3)
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1711,7 +1702,8 @@ begin
|
|||||||
len := AStream.ReadByte;
|
len := AStream.ReadByte;
|
||||||
SetLength(s, len);
|
SetLength(s, len);
|
||||||
AStream.ReadBuffer(s[1], len);
|
AStream.ReadBuffer(s[1], len);
|
||||||
Result := ansiToUTF8(s);
|
Result := ConvertEncoding(s, FCodePage, encodingUTF8);
|
||||||
|
// Result := ansiToUTF8(s);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Reads a STRING record. It immediately precedes a FORMULA record which has a
|
{ Reads a STRING record. It immediately precedes a FORMULA record which has a
|
||||||
@ -1806,7 +1798,7 @@ end;
|
|||||||
function TsSpreadBIFFWriter.GetLastRowIndex(AWorksheet: TsWorksheet): Integer;
|
function TsSpreadBIFFWriter.GetLastRowIndex(AWorksheet: TsWorksheet): Integer;
|
||||||
begin
|
begin
|
||||||
FLastRow := 0;
|
FLastRow := 0;
|
||||||
IterateThroughCells(nil, AWorksheet.Cells, GetLastRowCallback);
|
IterateThroughCells(nil, AWorksheet.Cells, @GetLastRowCallback);
|
||||||
Result := FLastRow;
|
Result := FLastRow;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1819,7 +1811,7 @@ end;
|
|||||||
function TsSpreadBIFFWriter.GetLastColIndex(AWorksheet: TsWorksheet): Word;
|
function TsSpreadBIFFWriter.GetLastColIndex(AWorksheet: TsWorksheet): Word;
|
||||||
begin
|
begin
|
||||||
FLastCol := 0;
|
FLastCol := 0;
|
||||||
IterateThroughCells(nil, AWorksheet.Cells, GetLastColCallback);
|
IterateThroughCells(nil, AWorksheet.Cells, @GetLastColCallback);
|
||||||
Result := FLastCol;
|
Result := FLastCol;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1878,28 +1870,44 @@ begin
|
|||||||
AStream.WriteBuffer(rec, SizeOf(rec));
|
AStream.WriteBuffer(rec, SizeOf(rec));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFFWriter.WriteCodepage(AStream: TStream;
|
{@@ ----------------------------------------------------------------------------
|
||||||
AEncoding: TsEncoding);
|
Writes the code page identifier defined by the workbook to the stream.
|
||||||
|
BIFF2 has to be overridden because is uses cp1252, but has a different
|
||||||
|
number code.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadBIFFWriter.WriteCodepage(AStream: TStream; ACodePage: String);
|
||||||
|
// AEncoding: TsEncoding);
|
||||||
var
|
var
|
||||||
lCodepage: Word;
|
cp: Word;
|
||||||
begin
|
begin
|
||||||
{ BIFF Record header }
|
{ BIFF Record header }
|
||||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_CODEPAGE));
|
AStream.WriteWord(WordToLE(INT_EXCEL_ID_CODEPAGE));
|
||||||
AStream.WriteWord(WordToLE(2));
|
AStream.WriteWord(WordToLE(2));
|
||||||
|
|
||||||
{ Codepage }
|
{ Codepage }
|
||||||
case AEncoding of
|
FCodePage := lowercase(ACodePage);
|
||||||
seLatin2: lCodepage := WORD_CP_1250_Latin2;
|
case FCodePage of
|
||||||
seCyrillic: lCodepage := WORD_CP_1251_Cyrillic;
|
'ucs2le': cp := WORD_UTF_16; // Biff 7
|
||||||
seGreek: lCodepage := WORD_CP_1253_Greek;
|
'cp437' : cp := WORD_CP_437_DOS_US;
|
||||||
seTurkish: lCodepage := WORD_CP_1254_Turkish;
|
'cp850' : cp := WORD_CP_850_DOS_Latin1;
|
||||||
seHebrew: lCodepage := WORD_CP_1255_Hebrew;
|
'cp852' : cp := WORD_CP_852_DOS_Latin2;
|
||||||
seArabic: lCodepage := WORD_CP_1256_Arabic;
|
'cp866' : cp := WORD_CP_866_DOS_Cyrillic;
|
||||||
|
'cp874' : cp := WORD_CP_874_Thai;
|
||||||
|
'cp1250': cp := WORD_CP_1250_Latin2;
|
||||||
|
'cp1251': cp := WORD_CP_1251_Cyrillic;
|
||||||
|
'cp1252': cp := WORD_CP_1252_Latin1;
|
||||||
|
'cp1253': cp := WORD_CP_1253_Greek;
|
||||||
|
'cp1254': cp := WORD_CP_1254_Turkish;
|
||||||
|
'cp1255': cp := WORD_CP_1255_Hebrew;
|
||||||
|
'cp1256': cp := WORD_CP_1256_Arabic;
|
||||||
|
'cp1257': cp := WORD_CP_1257_Baltic;
|
||||||
|
'cp1258': cp := WORD_CP_1258_Vietnamese;
|
||||||
else
|
else
|
||||||
// Default is Latin1
|
Workbook.AddErrorMsg(rsCodePageNotSupported, [FCodePage]);
|
||||||
lCodepage := WORD_CP_1252_Latin1;
|
FCodePage := 'cp1252';
|
||||||
|
cp := WORD_CP_1252_Latin1;
|
||||||
end;
|
end;
|
||||||
AStream.WriteWord(WordToLE(lCodepage));
|
AStream.WriteWord(WordToLE(cp));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Writes column info for the given column. Currently only the colum width is used.
|
{ Writes column info for the given column. Currently only the colum width is used.
|
||||||
@ -1958,7 +1966,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Writes a NOTE record which describes a comment attached to a cell }
|
{ Writes a NOTE record which describes a comment attached to a cell
|
||||||
|
Valid für Biff2 and BIFF5}
|
||||||
procedure TsSpreadBIFFWriter.WriteComment(AStream: TStream; ACell: PCell);
|
procedure TsSpreadBIFFWriter.WriteComment(AStream: TStream; ACell: PCell);
|
||||||
const
|
const
|
||||||
CHUNK_SIZE = 2048;
|
CHUNK_SIZE = 2048;
|
||||||
@ -1977,7 +1986,7 @@ begin
|
|||||||
|
|
||||||
List := TStringList.Create;
|
List := TStringList.Create;
|
||||||
try
|
try
|
||||||
List.Text := UTF8ToAnsi(ACell^.Comment);
|
List.Text := ConvertEncoding(ACell^.Comment, encodingUTF8, FCodePage);
|
||||||
comment := List[0];
|
comment := List[0];
|
||||||
for p := 1 to List.Count-1 do
|
for p := 1 to List.Count-1 do
|
||||||
comment := comment + #$0A + List[p];
|
comment := comment + #$0A + List[p];
|
||||||
@ -2402,8 +2411,8 @@ begin
|
|||||||
shared formula RECORD here. The shared formula RECORD must follow the
|
shared formula RECORD here. The shared formula RECORD must follow the
|
||||||
first FORMULA record referring to the shared formula}
|
first FORMULA record referring to the shared formula}
|
||||||
if (ACell^.SharedFormulaBase <> nil) and
|
if (ACell^.SharedFormulaBase <> nil) and
|
||||||
(ARow = ACell^.SharedFormulaBase.Row) and
|
(ARow = ACell^.SharedFormulaBase^.Row) and
|
||||||
(ACol = ACell^.SharedFormulaBase.Col)
|
(ACol = ACell^.SharedFormulaBase^.Col)
|
||||||
then
|
then
|
||||||
WriteSharedFormula(AStream, ACell^.SharedFormulaBase);
|
WriteSharedFormula(AStream, ACell^.SharedFormulaBase);
|
||||||
|
|
||||||
@ -2484,8 +2493,8 @@ var
|
|||||||
begin
|
begin
|
||||||
rec.FormulaSize := WordToLE(5);
|
rec.FormulaSize := WordToLE(5);
|
||||||
rec.Token := INT_EXCEL_TOKEN_TEXP; // Marks the cell for using a shared formula
|
rec.Token := INT_EXCEL_TOKEN_TEXP; // Marks the cell for using a shared formula
|
||||||
rec.Row := WordToLE(ACell^.SharedFormulaBase.Row);
|
rec.Row := WordToLE(ACell^.SharedFormulaBase^.Row);
|
||||||
rec.Col := WordToLE(ACell^.SharedFormulaBase.Col);
|
rec.Col := WordToLE(ACell^.SharedFormulaBase^.Col);
|
||||||
AStream.WriteBuffer(rec, SizeOf(rec));
|
AStream.WriteBuffer(rec, SizeOf(rec));
|
||||||
RPNLength := SizeOf(rec);
|
RPNLength := SizeOf(rec);
|
||||||
end;
|
end;
|
||||||
@ -2929,7 +2938,7 @@ var
|
|||||||
len: Byte;
|
len: Byte;
|
||||||
s: ansistring;
|
s: ansistring;
|
||||||
begin
|
begin
|
||||||
s := UTF8ToAnsi(AString);
|
s := ConvertEncoding(AString, encodingUTF8, FCodePage);
|
||||||
len := Length(s);
|
len := Length(s);
|
||||||
AStream.WriteByte(len);
|
AStream.WriteByte(len);
|
||||||
AStream.WriteBuffer(s[1], len);
|
AStream.WriteBuffer(s[1], len);
|
||||||
|
@ -2395,6 +2395,8 @@ end;
|
|||||||
|
|
||||||
procedure TsSpreadOOXMLWriter.WriteWorksheetRels(AWorksheet: TsWorksheet);
|
procedure TsSpreadOOXMLWriter.WriteWorksheetRels(AWorksheet: TsWorksheet);
|
||||||
begin
|
begin
|
||||||
|
Unused(AWorksheet);
|
||||||
|
|
||||||
// Create stream
|
// Create stream
|
||||||
SetLength(FSSheetRels, FCurSheetNum + 1);
|
SetLength(FSSheetRels, FCurSheetNum + 1);
|
||||||
if (boBufStream in Workbook.Options) then
|
if (boBufStream in Workbook.Options) then
|
||||||
|
Reference in New Issue
Block a user