📄 rm_wawwriters.pas
字号:
while Result < XLSMaxColorsInPalette do
begin
if (DefaultColorIndex(FColorPalette[Result]) = -1) and
(FUsedColors.IndexOf(Pointer(FColorPalette[Result])) = -1) then
begin
// replace color in palette with new color
FColorPalette[Result] := Color;
FPaletteModified := true;
Result := Result + 8;
exit;
end;
Inc(Result);
end;
Result := 8; // return index to BLACK color
end;
function sort(Item1: Pointer; Item2: Pointer): Integer;
begin
Result := TwawXLSRange(Item1).Place.Left - TwawXLSRange(Item2).Place.Left;
end;
procedure TwawExcelWriter.WriteRangeToStream(Stream: TStream;
Range: TwawXLSRange; CurrentRow: Integer;
var IndexInCellsOffsArray: Integer;
var CellsOffs: Tb8DBCELLCellsOffsArray);
var
blank: rb8BLANK;
i: Integer;
Left: Integer;
number: rb8NUMBER;
mulblank: pb8MULBLANK;
labelsst: rb8LABELSST;
formula: pb8FORMULA;
procedure AddToCellsOffsArray;
begin
if IndexInCellsOffsArray = 0 then
CellsOffs[IndexInCellsOffsArray] := Stream.Position
else
CellsOffs[IndexInCellsOffsArray] := Stream.Position - CellsOffs[IndexInCellsOffsArray - 1];
Inc(IndexInCellsOffsArray);
end;
begin
Left := Range.Place.Left;
if CurrentRow = Range.Place.Top then
begin
// write data cell, check cell type
case Range.CellDataType of
wawcdtNumber:
begin
AddToCellsOffsArray;
number.rw := CurrentRow;
number.col := Left;
number.ixfe := pXLSRangeRec(Range.ExportData).iXF;
number.num := Range.Value;
wbiff(Stream, b8_NUMBER, @number, sizeof(rb8NUMBER));
Inc(Left);
end;
wawcdtString:
begin
if pXLSRangeRec(Range.ExportData).iSST <> -1 then
begin
AddToCellsOffsArray;
labelsst.rw := CurrentRow;
labelsst.col := Left;
labelsst.ixfe := pXLSRangeRec(Range.ExportData).iXF;
labelsst.isst := pXLSRangeRec(Range.ExportData).iSST;
wbiff(Stream, b8_LABELSST, @labelsst, sizeof(labelsst));
Inc(Left);
end;
end;
wawcdtFormula:
begin
AddToCellsOffsArray;
formula := AllocMem(pXLSRangeRec(Range.ExportData).PtgsSize + sizeof(rb8FORMULA));
try
formula.rw := CurrentRow;
formula.col := Left;
formula.ixfe := pXLSRangeRec(Range.ExportData).iXF;
formula.value := 0;
formula.grbit := 1;
formula.chn := 0;
formula.cce := pXLSRangeRec(Range.ExportData).PtgsSize;
MoveMemory(PChar(PChar(formula) + sizeof(rb8FORMULA)),
pXLSRangeRec(Range.ExportData).Ptgs,
pXLSRangeRec(Range.ExportData).PtgsSize);
wbiff(Stream, b8_FORMULA, formula, pXLSRangeRec(Range.ExportData).PtgsSize + sizeof(rb8FORMULA));
Inc(Left);
finally
FreeMem(formula);
end;
end;
end;
end;
if Left < Range.Place.Right then
begin
AddToCellsOffsArray;
mulblank := AllocMem(sizeof(rb8MULBLANK) + (Range.Place.Right - Left + 1) * 2 + 2);
try
mulblank.rw := CurrentRow;
mulblank.colFirst := Left;
for i := 0 to Range.Place.Right - Left do
PWordArray(PChar(mulblank) + sizeof(rb8MULBLANK))^[i] := pXLSRangeRec(Range.ExportData).iXF;
PWord(PChar(mulblank) + sizeof(rb8MULBLANK) + (Range.Place.Right - Left + 1) * 2)^ := Range.Place.Right;
wbiff(Stream, b8_MULBLANK, mulblank, sizeof(rb8MULBLANK) + (Range.Place.Right - Left + 1) * 2 + 2);
finally
FreeMem(mulblank);
end;
end
else
if Left = Range.Place.Right then
begin
AddToCellsOffsArray;
blank.rw := CurrentRow;
blank.col := Left;
blank.ixfe := pXLSRangeRec(Range.ExportData).iXF;
wbiff(Stream, b8_BLANK, @blank, sizeof(blank));
end;
end;
procedure TwawExcelWriter.WriteSheetToStream(Stream: TStream; Sheet: TwawXLSWorksheet);
var
s: string;
bof: rb8BOF;
guts: rb8GUTS;
wsbool: rb8WSBOOL;
header: pb8HEADER;
footer: pb8FOOTER;
hcenter: rb8HCENTER;
vcenter: rb8VCENTER;
refmode: rb8REFMODE;
gridset: rb8GRIDSET;
window2: rb8WINDOW2;
calcmode: rb8CALCMODE;
calccount: rb8CALCCOUNT;
iteration: rb8ITERATION;
selection: pb8SELECTION;
saverecalc: rb8SAVERECALC;
dimensions: rb8DIMENSIONS;
defcolwidth: rb8DEFCOLWIDTH;
printheaders: rb8PRINTHEADERS;
printgridlines: rb8PRINTGRIDLINES;
defaultrowheight: rb8DEFAULTROWHEIGHT;
l: TList;
rw: TwawXLSRow;
ran: TwawXLSRange;
row: rb8ROW;
bc: Integer;
i: Integer;
j: Integer;
index: pb8INDEX;
INDEXOffs: Integer;
BlocksInSheet: Integer;
IndexInDBCELLsOffs: Integer;
dbcell: rb8DBCELLfull;
IndexInCellsOffsArray: Integer;
ms: TMemoryStream;
merge: PChar;
colinfo: rb8COLINFO;
FirstRowOffs: Integer;
SecondRowOffs: Integer;
setup: rb8SETUP;
topmargin: rb8TOPMARGIN;
leftmargin: rb8LEFTMARGIN;
rightmargin: rb8RIGHTMARGIN;
bottommargin: rb8BOTTOMMARGIN;
horizontalpagebreaks: pb8HORIZONTALPAGEBREAKS;
begin
ZeroMemory(@bof, sizeof(bof));
bof.vers := b8_BOF_vers;
bof.dt := b8_BOF_dt_Worksheet;
bof.rupBuild := b8_BOF_rupBuild_Excel97;
bof.rupYear := b8_BOF_rupYear_Excel07;
wbiff(Stream, b8_BOF, @bof, sizeof(bof));
if (Sheet.Dimensions.Bottom <> -1) and (Sheet.Dimensions.Top <> -1) then
begin
BlocksInSheet := (Sheet.Dimensions.Bottom - Sheet.Dimensions.Top + 1) div XLSMaxRowsInBlock;
if (Sheet.Dimensions.Bottom = Sheet.Dimensions.Top) or (((Sheet.Dimensions.Bottom - Sheet.Dimensions.Top + 1) mod XLSMaxRowsInBlock) <> 0) then
Inc(BlocksInSheet);
end
else
BlocksInSheet := 0;
index := AllocMem(sizeof(rb8INDEX) + BlocksInSheet * 4);
try
if (Sheet.Dimensions.Bottom <> -1) and (Sheet.Dimensions.Top <> -1) then
begin
index.rwMic := Sheet.Dimensions.Top;
index.rwMac := Sheet.Dimensions.Bottom + 1;
end;
INDEXOffs := Stream.Position;
IndexInDBCELLsOffs := 0;
wbiff(Stream, b8_INDEX, index, sizeof(rb8INDEX) + BlocksInSheet * 4); // corrected later
calcmode.fAutoRecalc := 1; // automatic recalc
wbiff(Stream, b8_CALCMODE, @calcmode, sizeof(calcmode));
calccount.cIter := $0064; // see in biffview
wbiff(Stream, b8_CALCCOUNT, @calccount, sizeof(calccount));
refmode.fRefA1 := $0001; // 1 for A1 mode
wbiff(Stream, b8_REFMODE, @refmode, sizeof(refmode));
iteration.fIter := $0000; // 1 see in biffview
wbiff(Stream, b8_ITERATION, @iteration, sizeof(iteration));
// DELTA
s := HexStringToString('10 00 08 00 fc a9 f1 d2 4d 62 50 3f');
UniqueString(s);
Stream.Write(s[1], length(s));
saverecalc.fSaveRecalc := $0001; // see in biffview
wbiff(Stream, b8_SAVERECALC, @saverecalc, sizeof(saverecalc));
if Sheet.PageSetup.PrintHeaders then
printheaders.fPrintRwCol := 1
else
printheaders.fPrintRwCol := 0;
wbiff(Stream, b8_PRINTHEADERS, @printheaders, sizeof(printheaders));
if Sheet.PageSetup.PrintGridLines then
printgridlines.fPrintGrid := 1
else
printgridlines.fPrintGrid := 0;
wbiff(Stream, b8_PRINTGRIDLINES, @printgridlines, sizeof(printgridlines));
gridset.fGridSet := $0001; // see in biffview
wbiff(Stream, b8_GRIDSET, @gridset, sizeof(gridset));
ZeroMemory(@guts, sizeof(guts)); // all to zero see in biffview
wbiff(Stream, b8_GUTS, @guts, sizeof(guts));
defaultrowheight.grbit := $0000; // see in biffview
defaultrowheight.miyRw := xlsDefaultRowHeight; // see in biffview
wbiff(Stream, b8_DEFAULTROWHEIGHT, @defaultrowheight, sizeof(defaultrowheight));
if Sheet.PageBreaksCount > 0 then
begin
horizontalpagebreaks := AllocMem(Sheet.PageBreaksCount * sizeof(rb8HORIZONTALPAGEBREAK) + 2);
try
horizontalpagebreaks.cbrk := Sheet.PageBreaksCount;
for i := 0 to Sheet.PageBreaksCount - 1 do
begin
pb8HORIZONTALPAGEBREAK(PCHAR(horizontalpagebreaks) + sizeof(rb8HORIZONTALPAGEBREAKS) +
sizeof(rb8HORIZONTALPAGEBREAK) * i)^.row := Sheet.PageBreaks[i];
pb8HORIZONTALPAGEBREAK(PCHAR(horizontalpagebreaks) + sizeof(rb8HORIZONTALPAGEBREAKS) +
sizeof(rb8HORIZONTALPAGEBREAK) * i)^.startcol := $0000;
pb8HORIZONTALPAGEBREAK(PCHAR(horizontalpagebreaks) + sizeof(rb8HORIZONTALPAGEBREAKS) +
sizeof(rb8HORIZONTALPAGEBREAK) * i)^.endcol := $00FF;
end;
wbiff(Stream, b8_HORIZONTALPAGEBREAKS, horizontalpagebreaks,
Sheet.PageBreaksCount * sizeof(rb8HORIZONTALPAGEBREAK) + sizeof(rb8HORIZONTALPAGEBREAKS));
finally
FreeMem(horizontalpagebreaks);
end;
end;
wsbool.grbit := $04C1; // see in biffview
wbiff(Stream, b8_WSBOOL, @wsbool, sizeof(wsbool));
s := '';
if Sheet.PageSetup.LeftHeader <> '' then
s := s + '&L' + Sheet.PageSetup.LeftHeader;
if Sheet.PageSetup.CenterHeader <> '' then
s := s + '&C' + Sheet.PageSetup.CenterHeader;
if Sheet.PageSetup.RightHeader <> '' then
s := s + '&R' + Sheet.PageSetup.RightHeader;
if s <> '' then
begin
GetMem(header, sizeof(rb8HEADER) + Length(s) * sizeof(WideChar));
try
i := FormatStrToWideChar(s, PWideChar(PChar(header) + sizeof(rb8HEADER)));
header.cch := i;
header.cchgrbit := 1;
wbiff(Stream, b8_HEADER, header, sizeof(rb8HEADER) + (i shl 1));
finally
FreeMem(header);
end;
end
else
wbiff(Stream, b8_HEADER, nil, 0);
s := '';
if Sheet.PageSetup.LeftFooter <> '' then
s := s + '&L' + Sheet.PageSetup.LeftFooter;
if Sheet.PageSetup.CenterFooter <> '' then
s := s + '&C' + Sheet.PageSetup.CenterFooter;
if Sheet.PageSetup.RightFooter <> '' then
s := s + '&R' + Sheet.PageSetup.RightFooter;
if s <> '' then
begin
GetMem(footer, sizeof(rb8FOOTER) + Length(s) * sizeof(WideChar));
try
i := FormatStrToWideChar(s, PWideChar(PChar(footer) + sizeof(rb8HEADER)));
footer.cch := i;
footer.cchgrbit := 1;
wbiff(Stream, b8_FOOTER, footer, sizeof(rb8FOOTER) + (i shl 1));
finally
FreeMem(footer);
end;
end
else
wbiff(Stream, b8_FOOTER, nil, 0);
if Sheet.PageSetup.CenterHorizontally then
hcenter.fHCenter := 1
else
hcenter.fHCenter := 0;
wbiff(Stream, b8_HCENTER, @hcenter, sizeof(hcenter));
if Sheet.PageSetup.CenterVertically then
vcenter.fVCenter := 1
else
vcenter.fVCenter := 0;
wbiff(Stream, b8_VCENTER, @vcenter, sizeof(vcenter));
leftmargin.num := Sheet.PageSetup.LeftMargin;
wbiff(Stream, b8_LEFTMARGIN, @leftmargin, sizeof(rb8LEFTMARGIN));
rightmargin.num := Sheet.PageSetup.RightMargin;
wbiff(Stream, b8_RIGHTMARGIN, @rightmargin, sizeof(rb8RIGHTMARGIN));
topmargin.num := Sheet.PageSetup.TopMargin;
wbiff(Stream, b8_TOPMARGIN, @topmargin, sizeof(rb8TOPMARGIN));
bottommargin.num := Sheet.PageSetup.BottomMargin;
wbiff(Stream, b8_BOTTOMMARGIN, @bottommargin, sizeof(rb8BOTTOMMARGIN));
ZeroMemory(@setup, sizeof(rb8SETUP));
setup.iPaperSize := word(Sheet.PageSetup.PaperSize);
setup.iPageStart := Sheet.PageSetup.FirstPageNumber;
setup.iFitWidth := Sheet.PageSetup.FitToPagesWide;
setup.iFitHeight := Sheet.PageSetup.FitToPagesTall;
setup.numHdr := Sheet.PageSetup.HeaderMargin;
setup.numFtr := Sheet.PageSetup.FooterMargin;
setup.iCopies := Sheet.PageSetup.Copies;
setup.iScale := Sheet.PageSetup.Zoom;
// setup.grbit := b8_SETUP_fNoPls;
if Sheet.PageSetup.Order = wawxlOverThenDown then
setup.grbit := setup.grbit or b8_SETUP_fLeftToRight;
if Sheet.PageSetup.Orientation = wawxlPortrait then
setup.grbit := setup.grbit or b8_SETUP_fLandscape;
if Sheet.PageSetup.BlackAndWhite then
setup.grbit := setup.grbit or b8_SETUP_fNoColor;
if Sheet.PageSetup.Draft then
setup.grbit := setup.grbit or b8_SETUP_fDraft;
if Sheet.PageSetup.PrintNotes then
setup.grbit := setup.grbit or b8_SETUP_fNotes;
if Sheet.PageSetup.FirstPageNumber <> 1 then
setup.grbit := setup.grbit or b8_SETUP_fUsePage;
wbiff(Stream, b8_SETUP, @setup, sizeof(rb8SETUP));
defcolwidth.cchdefColWidth := XLSDefaultColumnWidthInChars; // see in biffview
wbiff(Stream, b8_DEFCOLWIDTH, @defcolwidth, sizeof(defcolwidth));
for i := 0 to Sheet.ColsCount - 1 do
with Sheet.ColByIndex[i] do
begin
ZeroMemory(@colinfo, sizeof(colinfo));
colinfo.colFirst := Ind;
colinfo.colLast := Ind;
colinfo.coldx := Width;
colinfo.ixfe := $0F; //waw see from *.xls
colinfo.grbit := $02; //waw
if Width = 0 then
colinfo.grbit := colinfo.grbit or $01; //waw
colinfo.res1 := $02; //waw
wbiff(Stream, b8_COLINFO, @colinfo, sizeof(colinfo));
end;
ZeroMemory(@dimensions, sizeof(dimensions));
if (Sheet.Dimensions.Left <> -1) and
(Sheet.Dimensions.Right <> -1) and
(Sheet.Dimensions.Top <> -1) and
(Sheet.Dimensions.Bottom <> -1) then
begin
dimensions.rwMic := Sheet.Dimensions.Top;
dimensions.rwMac := Sheet.Dimensions.Bottom + 1;
dimensions.colMic := Sheet.Dimensions.Left;
dimensions.colMac := Sheet.Dimensions.Right + 1;
end;
wbiff(Stream, b8_DIMENSIONS, @dimensions, sizeof(dimensions));
if (Sheet.Dimensions.Top <> -1) and (Sheet.Dimensions.Bottom <> -1) then
begin
l := TList.Create;
ms := TMemoryStream.Create;
try
bc := 0;
FirstRowOffs := 0;
SecondRowOffs := 0;
for i := Sheet.Dimensions.Top to Sheet.Dimensions.Bottom do
begin
// finding all regions what placed over row [i]
l.Clear;
for j := 0 to Sheet.RangesCount - 1 do
begin
ran := Sheet.RangeByIndex[j];
if (ran.Place.Top <= i) and (i <= ran.Place.Bottom) then
l.Add(ran);
end;
l.Sort(sort);
// write row i to file
if bc = 0 then
FirstRowOffs := Stream.Position;
row.rw := i;
if l.Count > 0 then
begin
row.colMic := TwawXLSRange(l[0]).Place.Left;
row.colMac := TwawXLSRange(l[l.Count - 1]).Place.Right + 1;
end
else
begin
row.colMic := 0;
row.colMac := 0;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -