You've already forked lazarus-ccr
fpspreadsheet: Read/write worksheet hidden state for biff8 and biff5.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5775 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -100,7 +100,7 @@ type
|
||||
procedure InternalWriteToStream(AStream: TStream);
|
||||
{ Record writing methods }
|
||||
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
||||
function WriteBoundsheet(AStream: TStream; ASheetName: string): Int64;
|
||||
function WriteBoundsheet(AStream: TStream; AWorkSheet: TsWorksheet): Int64;
|
||||
procedure WriteDefinedName(AStream: TStream; AWorksheet: TsWorksheet;
|
||||
const AName: String; AIndexToREF: Word); override;
|
||||
procedure WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
@ -364,9 +364,10 @@ end;
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFF5Reader.ReadBoundsheet(AStream: TStream);
|
||||
var
|
||||
Len: Byte;
|
||||
len: Byte;
|
||||
s: AnsiString;
|
||||
sheetName: String;
|
||||
sheetState: Byte;
|
||||
sheetData: TsSheetData;
|
||||
begin
|
||||
{ Absolute stream position of the BOF record of the sheet represented
|
||||
by this record }
|
||||
@ -374,18 +375,21 @@ begin
|
||||
AStream.ReadDWord();
|
||||
|
||||
{ Visibility }
|
||||
AStream.ReadByte();
|
||||
sheetState := AStream.ReadByte();
|
||||
|
||||
{ Sheet type }
|
||||
AStream.ReadByte();
|
||||
|
||||
{ Sheet name: Byte string, 8-bit length }
|
||||
Len := AStream.ReadByte();
|
||||
len := AStream.ReadByte();
|
||||
SetLength(s, len);
|
||||
AStream.ReadBuffer(s[1], len*SizeOf(AnsiChar));
|
||||
|
||||
SetLength(s, Len);
|
||||
AStream.ReadBuffer(s[1], Len*SizeOf(AnsiChar));
|
||||
sheetName := ConvertEncoding(s, FCodePage, EncodingUTF8);
|
||||
FWorksheetNames.Add(sheetName);
|
||||
{ Temporarily store parameters for worksheet in FSheetList }
|
||||
sheetData := TsSheetData.Create;
|
||||
sheetData.Name := ConvertEncoding(s, FCodePage, EncodingUTF8);
|
||||
sheetData.Hidden := sheetState <> 0;
|
||||
FSheetList.Add(sheetData);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -494,8 +498,12 @@ var
|
||||
SectionEOF: Boolean = False;
|
||||
RecordType: Word;
|
||||
CurStreamPos: Int64;
|
||||
sheetData: TsSheetData;
|
||||
begin
|
||||
FWorksheet := FWorkbook.AddWorksheet(FWorksheetNames[FCurSheetIndex], true);
|
||||
sheetData := TsSheetData(FSheetList[FCurSheetIndex]);
|
||||
FWorksheet := FWorkbook.AddWorksheet(sheetData.Name, true);
|
||||
if sheetData.Hidden then
|
||||
FWorksheet.Options := FWorksheet.Options + [soHidden];
|
||||
|
||||
while (not SectionEOF) do
|
||||
begin
|
||||
@ -1101,7 +1109,7 @@ end;
|
||||
procedure TsSpreadBIFF5Writer.InternalWriteToStream(AStream: TStream);
|
||||
var
|
||||
CurrentPos: Int64;
|
||||
Boundsheets: array of Int64;
|
||||
sheetPos: array of Int64;
|
||||
i: Integer;
|
||||
pane: Byte;
|
||||
begin
|
||||
@ -1121,9 +1129,9 @@ begin
|
||||
WriteStyle(AStream);
|
||||
|
||||
// A BOUNDSHEET for each worksheet
|
||||
SetLength(Boundsheets, Workbook.GetWorksheetCount);
|
||||
SetLength(sheetPos, Workbook.GetWorksheetCount);
|
||||
for i := 0 to Workbook.GetWorksheetCount - 1 do
|
||||
Boundsheets[i] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i).Name);
|
||||
sheetPos[i] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i));
|
||||
|
||||
WriteEOF(AStream);
|
||||
|
||||
@ -1136,7 +1144,7 @@ begin
|
||||
{ First goes back and writes the position of the BOF of the
|
||||
sheet on the respective BOUNDSHEET record }
|
||||
CurrentPos := AStream.Position;
|
||||
AStream.Position := Boundsheets[i];
|
||||
AStream.Position := sheetPos[i];
|
||||
AStream.WriteDWord(CurrentPos);
|
||||
AStream.Position := CurrentPos;
|
||||
|
||||
@ -1179,7 +1187,7 @@ begin
|
||||
|
||||
{ Cleanup }
|
||||
|
||||
SetLength(Boundsheets, 0);
|
||||
SetLength(sheetPos, 0);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -1281,13 +1289,15 @@ end;
|
||||
@return The stream position where the absolute stream position
|
||||
of the BOF of this sheet should be written (4 bytes size).
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsSpreadBIFF5Writer.WriteBoundsheet(AStream: TStream; ASheetName: string): Int64;
|
||||
function TsSpreadBIFF5Writer.WriteBoundsheet(AStream: TStream;
|
||||
AWorkSheet: TsWorksheet): Int64;
|
||||
var
|
||||
Len: Byte;
|
||||
len: Byte;
|
||||
xlsSheetName: ansistring;
|
||||
sheetState: Byte;
|
||||
begin
|
||||
xlsSheetName := ConvertEncoding(ASheetName, encodingUTF8, FCodePage);
|
||||
Len := Length(xlsSheetName);
|
||||
xlsSheetName := ConvertEncoding(AWorkSheet.Name, encodingUTF8, FCodePage);
|
||||
len := Length(xlsSheetName);
|
||||
{
|
||||
LatinSheetName := UTF8ToISO_8859_1(ASheetName);
|
||||
Len := Length(LatinSheetName);
|
||||
@ -1301,15 +1311,16 @@ begin
|
||||
AStream.WriteDWord(WordToLE(0));
|
||||
|
||||
{ Visibility }
|
||||
AStream.WriteByte(0);
|
||||
sheetState := IfThen(soHidden in AWorksheet.Options, 1, 0);
|
||||
AStream.WriteByte(sheetState);
|
||||
|
||||
{ Sheet type }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Sheet name: Byte string, 8-bit length }
|
||||
AStream.WriteByte(Len);
|
||||
AStream.WriteByte(len);
|
||||
// AStream.WriteBuffer(LatinSheetName[1], Len);
|
||||
AStream.WriteBuffer(xlsSheetName[1], Len);
|
||||
AStream.WriteBuffer(xlsSheetName[1], len);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
|
@ -65,7 +65,6 @@ uses
|
||||
fpsutils;
|
||||
|
||||
type
|
||||
|
||||
TBIFF8ExternSheet = packed record
|
||||
ExternBookIndex: Word;
|
||||
FirstSheetIndex: Word;
|
||||
@ -139,7 +138,7 @@ type
|
||||
|
||||
{ Record writing methods }
|
||||
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
||||
function WriteBoundsheet(AStream: TStream; ASheetName: string): Int64;
|
||||
function WriteBoundsheet(AStream: TStream; AWorksheet: TsWorksheet): Int64;
|
||||
procedure WriteComment(AStream: TStream; ACell: PCell); override;
|
||||
procedure WriteComments(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
procedure WriteDefinedName(AStream: TStream; AWorksheet: TsWorksheet;
|
||||
@ -454,6 +453,7 @@ type
|
||||
Text: String;
|
||||
end;
|
||||
|
||||
|
||||
{ TsSpreadBIFF8Reader }
|
||||
|
||||
destructor TsSpreadBIFF8Reader.Destroy;
|
||||
@ -830,8 +830,12 @@ var
|
||||
SectionEOF: Boolean = False;
|
||||
RecordType: Word;
|
||||
CurStreamPos: Int64;
|
||||
sheetData: TsSheetData;
|
||||
begin
|
||||
FWorksheet := FWorkbook.AddWorksheet(FWorksheetNames[FCurSheetIndex], true);
|
||||
sheetData := TsSheetData(FSheetList[FCurSheetIndex]);
|
||||
FWorksheet := FWorkbook.AddWorksheet(sheetData.Name, true);
|
||||
if sheetData.Hidden then
|
||||
FWorksheet.Options := FWorksheet.Options + [soHidden];
|
||||
|
||||
while (not SectionEOF) do
|
||||
begin
|
||||
@ -912,9 +916,11 @@ end;
|
||||
|
||||
procedure TsSpreadBIFF8Reader.ReadBoundsheet(AStream: TStream);
|
||||
var
|
||||
Len: Byte;
|
||||
WideName: WideString;
|
||||
len: Byte;
|
||||
wideName: WideString;
|
||||
rtParams: TsRichTextParams;
|
||||
sheetstate: Byte;
|
||||
sheetdata: TsSheetData;
|
||||
begin
|
||||
{ Absolute stream position of the BOF record of the sheet represented
|
||||
by this record }
|
||||
@ -922,18 +928,21 @@ begin
|
||||
AStream.ReadDWord();
|
||||
|
||||
{ Visibility }
|
||||
AStream.ReadByte();
|
||||
sheetstate := AStream.ReadByte(); // 0=visible, 1=hidden, 2="very" hidden
|
||||
|
||||
{ Sheet type }
|
||||
AStream.ReadByte();
|
||||
|
||||
{ Sheet name: 8-bit length }
|
||||
Len := AStream.ReadByte();
|
||||
len := AStream.ReadByte();
|
||||
|
||||
{ Read string with flags }
|
||||
WideName:=ReadWideString(AStream, Len, rtParams);
|
||||
wideName := ReadWideString(AStream, len, rtParams);
|
||||
|
||||
FWorksheetNames.Add(UTF8Encode(WideName));
|
||||
sheetData := TsSheetData.Create;
|
||||
sheetData.Name := UTF8Encode(wideName);
|
||||
sheetData.Hidden := sheetState <> 0;
|
||||
FSheetList.Add(sheetdata);
|
||||
end;
|
||||
|
||||
function TsSpreadBIFF8Reader.ReadString(const AStream: TStream;
|
||||
@ -2093,8 +2102,8 @@ procedure TsSpreadBIFF8Writer.InternalWriteToStream(AStream: TStream);
|
||||
const
|
||||
isBIFF8 = true;
|
||||
var
|
||||
CurrentPos: Int64;
|
||||
Boundsheets: array of Int64;
|
||||
currentPos: Int64;
|
||||
sheetPos: array of Int64;
|
||||
i: Integer;
|
||||
pane: Byte;
|
||||
begin
|
||||
@ -2109,9 +2118,9 @@ begin
|
||||
WriteStyle(AStream);
|
||||
|
||||
// A BOUNDSHEET for each worksheet
|
||||
SetLength(Boundsheets, Workbook.GetWorksheetCount);
|
||||
SetLength(sheetPos, Workbook.GetWorksheetCount);
|
||||
for i := 0 to Workbook.GetWorksheetCount - 1 do
|
||||
Boundsheets[i] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i).Name);
|
||||
sheetPos[i] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i));
|
||||
|
||||
WriteEXTERNBOOK(AStream);
|
||||
WriteEXTERNSHEET(AStream);
|
||||
@ -2126,10 +2135,10 @@ begin
|
||||
|
||||
{ First goes back and writes the position of the BOF of the
|
||||
sheet on the respective BOUNDSHEET record }
|
||||
CurrentPos := AStream.Position;
|
||||
AStream.Position := Boundsheets[i];
|
||||
currentPos := AStream.Position;
|
||||
AStream.Position := sheetPos[i];
|
||||
AStream.WriteDWord(DWordToLE(DWORD(CurrentPos)));
|
||||
AStream.Position := CurrentPos;
|
||||
AStream.Position := currentPos;
|
||||
|
||||
WriteBOF(AStream, INT_BOF_SHEET);
|
||||
WriteIndex(AStream);
|
||||
@ -2175,7 +2184,7 @@ begin
|
||||
end;
|
||||
|
||||
{ Cleanup }
|
||||
SetLength(Boundsheets, 0);
|
||||
SetLength(sheetPos, 0);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -2285,13 +2294,15 @@ end;
|
||||
@return The stream position where the absolute stream position
|
||||
of the BOF of this sheet should be written (4 bytes size).
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsSpreadBIFF8Writer.WriteBoundsheet(AStream: TStream; ASheetName: string): Int64;
|
||||
function TsSpreadBIFF8Writer.WriteBoundsheet(AStream: TStream;
|
||||
AWorksheet: TsWorksheet): Int64;
|
||||
var
|
||||
Len: Byte;
|
||||
WideSheetName: WideString;
|
||||
len: Byte;
|
||||
wideSheetName: WideString;
|
||||
sheetState: Byte;
|
||||
begin
|
||||
WideSheetName:=UTF8Decode(ASheetName);
|
||||
Len := Length(WideSheetName);
|
||||
wideSheetName := UTF8Decode(AWorksheet.Name);
|
||||
len := Length(wideSheetName);
|
||||
|
||||
{ BIFF Record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_BOUNDSHEET, 8 + Len * Sizeof(WideChar));
|
||||
@ -2302,7 +2313,8 @@ begin
|
||||
AStream.WriteDWord(DWordToLE(0));
|
||||
|
||||
{ Visibility }
|
||||
AStream.WriteByte(0);
|
||||
sheetState := IfThen(soHidden in AWorksheet.Options, 1, 0);
|
||||
AStream.WriteByte(sheetState);
|
||||
|
||||
{ Sheet type }
|
||||
AStream.WriteByte(0);
|
||||
@ -2311,7 +2323,7 @@ begin
|
||||
AStream.WriteByte(Len);
|
||||
{String flags}
|
||||
AStream.WriteByte(1);
|
||||
AStream.WriteBuffer(WideStringToLE(WideSheetName)[1], Len * Sizeof(WideChar));
|
||||
AStream.WriteBuffer(WideStringToLE(wideSheetName)[1], len * SizeOf(WideChar));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
|
@ -346,6 +346,12 @@ type
|
||||
function ConvertToExcelError(AValue: TsErrorValue): byte;
|
||||
|
||||
type
|
||||
{ TsSheetData }
|
||||
TsSheetData = class
|
||||
Name: String;
|
||||
Hidden: Boolean;
|
||||
end;
|
||||
|
||||
{ TsBIFFHeader }
|
||||
TsBIFFHeader = packed record
|
||||
RecordID: Word;
|
||||
@ -379,10 +385,11 @@ type
|
||||
FFirstNumFormatIndexInFile: Integer;
|
||||
FPalette: TsPalette;
|
||||
FDefinedNames: TFPList;
|
||||
FWorksheetNames: TStrings;
|
||||
FWorksheetData: TFPList;
|
||||
FCurSheetIndex: Integer;
|
||||
FActivePane: Integer;
|
||||
FExternSheets: TStrings;
|
||||
FSheetList: TFPList;
|
||||
|
||||
procedure AddBuiltinNumFormats; override;
|
||||
procedure ApplyCellFormatting(ACell: PCell; XFIndex: Word); virtual;
|
||||
@ -712,7 +719,6 @@ type
|
||||
TextLen: Word;
|
||||
end;
|
||||
|
||||
|
||||
function ConvertExcelDateTimeToDateTime(const AExcelDateNum: Double;
|
||||
ADateMode: TDateMode): TDateTime;
|
||||
begin
|
||||
@ -936,6 +942,8 @@ constructor TsSpreadBIFFReader.Create(AWorkbook: TsWorkbook);
|
||||
begin
|
||||
inherited Create(AWorkbook);
|
||||
|
||||
FSheetList := TFPList.Create;
|
||||
|
||||
FPalette := TsPalette.Create;
|
||||
PopulatePalette;
|
||||
|
||||
@ -967,6 +975,9 @@ begin
|
||||
for j:=0 to FDefinedNames.Count-1 do TObject(FDefinedNames[j]).Free;
|
||||
FDefinedNames.Free;
|
||||
|
||||
for j:= 0 to FSheetList.Count-1 do TObject(FSheetList[j]).Free;
|
||||
FSheetList.Free;
|
||||
|
||||
FExternSheets.Free;
|
||||
FPalette.Free;
|
||||
|
||||
@ -2893,8 +2904,6 @@ begin
|
||||
AStream.Position := 0;
|
||||
|
||||
{Initializations }
|
||||
FWorksheetNames := TStringList.Create;
|
||||
try
|
||||
FCurSheetIndex := 0;
|
||||
BIFFEOF := false;
|
||||
|
||||
@ -2918,7 +2927,7 @@ begin
|
||||
inc(FCurSheetIndex);
|
||||
// It can happen in files written by Office97 that the OLE directory is
|
||||
// at the end of the file.
|
||||
if FCurSheetIndex = FWorksheetNames.Count then
|
||||
if FCurSheetIndex = FSheetList.Count then
|
||||
BIFFEOF := true;
|
||||
end;
|
||||
|
||||
@ -2929,11 +2938,6 @@ begin
|
||||
ExtractPrintRanges(sheet);
|
||||
ExtractPrintTitles(sheet);
|
||||
end;
|
||||
|
||||
finally
|
||||
{ Finalization }
|
||||
FreeAndNil(FWorksheetNames);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user