⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rm_wawwriters.pas

📁 这是一个功能强大
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  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 + -