📄 rm_wawwriters.pas
字号:
(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;
// to determine row height find TwawXLSRow, if not found
// simple set default height
rw := Sheet.FindRow(i);
if rw=nil then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -