You've already forked lazarus-ccr
fpspreadsheet: Add some more page layout properties (page size, orientation etc) for all Excel and ods formats (ods implementation, however, not correct at the moment).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4103 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -66,6 +66,7 @@ type
|
||||
FRowStyleList: TFPList;
|
||||
FRowList: TFPList;
|
||||
FDateMode: TDateMode;
|
||||
FPageLayout: TsPageLayout;
|
||||
// Applies internally stored column widths to current worksheet
|
||||
procedure ApplyColWidths;
|
||||
// Applies a style to a cell
|
||||
@ -91,6 +92,7 @@ type
|
||||
protected
|
||||
FPointSeparatorSettings: TFormatSettings;
|
||||
procedure AddBuiltinNumFormats; override;
|
||||
procedure ReadAutomaticStyles(AStylesNode: TDOMNode);
|
||||
procedure ReadNumFormats(AStylesNode: TDOMNode);
|
||||
procedure ReadSettings(AOfficeSettingsNode: TDOMNode);
|
||||
procedure ReadStyles(AStylesNode: TDOMNode);
|
||||
@ -618,6 +620,8 @@ begin
|
||||
Workbook.UseDefaultPalette;
|
||||
// Initial base date in case it won't be read from file
|
||||
FDateMode := dm1899;
|
||||
// Initialize internal PageLayout record
|
||||
InitPageLayout(FPageLayout);
|
||||
end;
|
||||
|
||||
destructor TsSpreadOpenDocReader.Destroy;
|
||||
@ -850,6 +854,79 @@ begin
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
procedure TsSpreadOpenDocReader.ReadAutomaticStyles(AStylesNode: TDOMNode);
|
||||
var
|
||||
nodeName: String;
|
||||
layoutNode: TDOMNode;
|
||||
node: TDOMNode;
|
||||
s: String;
|
||||
begin
|
||||
if not Assigned(AStylesNode) then
|
||||
exit;
|
||||
layoutNode := AStylesNode.FirstChild;
|
||||
while layoutNode <> nil do
|
||||
begin
|
||||
nodeName := layoutNode.NodeName;
|
||||
if nodeName = 'style:page-layout' then begin
|
||||
s := GetAttrValue(layoutNode, 'style:name');
|
||||
if s = 'Mpm1' then
|
||||
begin
|
||||
node := layoutNode.FirstChild;
|
||||
while node <> nil do
|
||||
begin
|
||||
nodeName := node.NodeName;
|
||||
if nodeName = 'style:page-layout-properties' then
|
||||
begin
|
||||
s := GetAttrValue(node, 'fo:margin-top');
|
||||
if s <> '' then
|
||||
FPageLayout.TopMargin := PtsToMM(HTMLLengthStrToPts(s));
|
||||
|
||||
s := GetAttrValue(node, 'fo:margin-bottom');
|
||||
if s <> '' then
|
||||
FPageLayout.BottomMargin := PtsToMM(HTMLLengthStrToPts(s));
|
||||
|
||||
s := GetAttrValue(node, 'fo:margin-left');
|
||||
if s <> '' then
|
||||
FPageLayout.LeftMargin := PtsToMM(HTMLLengthStrToPts(s));
|
||||
|
||||
s := GetAttrValue(node, 'fo:margin-right');
|
||||
if s <> '' then
|
||||
FPageLayout.RightMargin := PtsToMM(HTMLLengthStrToPts(s));
|
||||
|
||||
s := GetAttrValue(node, 'style:scale-to');
|
||||
if (s <> '') then
|
||||
begin
|
||||
if s[Length(s)] = '%' then Delete(s, Length(s), 1);
|
||||
FPageLayout.ScalingFactor := StrToFloat(s, FPointSeparatorSettings);
|
||||
end;
|
||||
|
||||
s := GetAttrValue(node, 'style:print');
|
||||
if pos('grid', s) > 0 then
|
||||
Include(FPageLayout.Options, poPrintGridLines);
|
||||
if pos('headers', s) > 0 then
|
||||
Include(FPageLayout.Options, poPrintHeaders);
|
||||
if pos('annotations', s) > 0 then
|
||||
Include(FPageLayout.Options, poPrintCellComments);
|
||||
|
||||
s := GetAttrValue(node, 'style:print-page-order');
|
||||
if s = 'ltr' then // "left-to-right", the other option is "ttb = top-to-bottom"
|
||||
Include(FPageLayout.Options, poPrintPagesByRows);
|
||||
|
||||
s := GetAttrValue(node, 'style:first-page-number');
|
||||
if s = 'continue' then
|
||||
Exclude(FPageLayout.Options, poUseStartPageNumber)
|
||||
else
|
||||
if TryStrToInt(s, FPageLayout.StartPageNumber) then
|
||||
Include(FPageLayout.Options, poUseStartPageNumber);
|
||||
end;
|
||||
node := node.NextSibling;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
layoutNode := layoutNode.NextSibling;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadOpenDocReader.ReadBlank(ARow, ACol: Cardinal;
|
||||
ACellNode: TDOMNode);
|
||||
var
|
||||
@ -1317,6 +1394,9 @@ begin
|
||||
ReadNumFormats(StylesNode);
|
||||
ReadStyles(StylesNode);
|
||||
|
||||
StylesNode := Doc.DocumentElement.FindNode('office:automatic-styles');
|
||||
ReadAutomaticStyles(StylesNode);
|
||||
|
||||
Doc.Free;
|
||||
|
||||
//process the content.xml file
|
||||
@ -1349,6 +1429,7 @@ begin
|
||||
continue;
|
||||
end;
|
||||
FWorkSheet := FWorkbook.AddWorksheet(GetAttrValue(TableNode,'table:name'), true);
|
||||
FWorksheet.PageLayout := FPageLayout;
|
||||
// Collect column styles used
|
||||
ReadColumns(TableNode);
|
||||
// Process each row inside the sheet and process each cell of the row
|
||||
|
@ -105,7 +105,6 @@ type
|
||||
FDefaultColWidth: Single; // in "characters". Excel uses the width of char "0" in 1st font
|
||||
FDefaultRowHeight: Single; // in "character heights", i.e. line count
|
||||
FSortParams: TsSortParams; // Parameters of the current sorting operation
|
||||
FPageLayout: TsPageLayout;
|
||||
FOnChangeCell: TsCellEvent;
|
||||
FOnChangeFont: TsCellEvent;
|
||||
FOnCompareCells: TsCellCompareEvent;
|
||||
@ -138,6 +137,9 @@ type
|
||||
procedure ExchangeCells(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
||||
|
||||
public
|
||||
{@@ Page layout parameters for printing }
|
||||
PageLayout: TsPageLayout;
|
||||
|
||||
{ Base methods }
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -468,8 +470,6 @@ type
|
||||
{@@ The default row height is given in "line count" (height of the
|
||||
default font }
|
||||
property DefaultRowHeight: Single read FDefaultRowHeight write FDefaultRowHeight;
|
||||
{@@ Page layout parameters for printing }
|
||||
property PageLayout: TsPageLayout read FPageLayout write FPageLayout;
|
||||
|
||||
// These are properties to interface to TsWorksheetGrid
|
||||
{@@ Parameters controlling visibility of grid lines and row/column headers,
|
||||
@ -1114,14 +1114,7 @@ begin
|
||||
FMergedCells := TsMergedCells.Create;
|
||||
FHyperlinks := TsHyperlinks.Create;
|
||||
|
||||
with FPageLayout do begin
|
||||
LeftMargin := InToPts(0.7);
|
||||
RightMargin := InToPts(0.7);
|
||||
TopMargin := InToPts(0.78740157499999996);
|
||||
BottomMargin := InToPts(0.78740157499999996);
|
||||
HeaderDistance := InToPts(0.3);
|
||||
FooterDistance := InToPts(0.3);
|
||||
end;
|
||||
InitPageLayout(PageLayout);
|
||||
|
||||
FDefaultColWidth := 12;
|
||||
FDefaultRowHeight := 1;
|
||||
@ -6767,6 +6760,8 @@ begin
|
||||
// Remember the workbook to which it belongs (This must occur before
|
||||
// setting the workbook name because the workbook is needed there).
|
||||
Result.FWorkbook := Self;
|
||||
Result.FActiveCellRow := 0;
|
||||
Result.FActiveCellCol := 0;
|
||||
|
||||
// Set the name of the new worksheet.
|
||||
// For this we turn off notification of listeners. This is not necessary here
|
||||
|
@ -2881,6 +2881,9 @@ end;
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadsheetInspector.UpdateWorksheet(ASheet: TsWorksheet;
|
||||
AStrings: TStrings);
|
||||
var
|
||||
s: String;
|
||||
po: TsPrintOption;
|
||||
begin
|
||||
if ASheet = nil then
|
||||
begin
|
||||
@ -2891,6 +2894,7 @@ begin
|
||||
AStrings.Add('Last column=');
|
||||
AStrings.Add('Active cell=');
|
||||
AStrings.Add('Selection=');
|
||||
AStrings.Add('Page layout=');
|
||||
end else
|
||||
begin
|
||||
AStrings.Add(Format('Name=%s', [ASheet.Name]));
|
||||
@ -2903,6 +2907,27 @@ begin
|
||||
AStrings.Add(Format('Comments=%d items', [ASheet.Comments.Count]));
|
||||
AStrings.Add(Format('Hyperlinks=%d items', [ASheet.Hyperlinks.Count]));
|
||||
AStrings.Add(Format('MergedCells=%d items', [ASheet.MergedCells.Count]));
|
||||
AStrings.Add('Page layout=');
|
||||
AStrings.Add(Format(' Orientation=%s', [GetEnumName(TypeInfo(TsPageOrientation), ord(ASheet.PageLayout.Orientation))]));
|
||||
AStrings.Add(Format(' Page width=%.1f mm', [ASheet.PageLayout.PageWidth]));
|
||||
AStrings.Add(Format(' Page height=%.1f mm', [ASheet.PageLayout.PageHeight]));
|
||||
AStrings.Add(Format(' Left margin=%.1f mm', [ASheet.PageLayout.LeftMargin]));
|
||||
AStrings.Add(Format(' Right margin=%.1f mm', [ASheet.PageLayout.RightMargin]));
|
||||
AStrings.Add(Format(' Top margin=%.1f mm', [ASheet.PageLayout.TopMargin]));
|
||||
AStrings.Add(Format(' Bottom margin=%.1f mm', [ASheet.PageLayout.BottomMargin]));
|
||||
AStrings.Add(Format(' Header distance=%.1f mm', [ASheet.PageLayout.HeaderMargin]));
|
||||
AStrings.Add(Format(' Footer distance=%.1f mm', [ASheet.PageLayout.FooterMargin]));
|
||||
if poUseStartPageNumber in ASheet.PageLayout.Options then
|
||||
AStrings.Add(Format(' Start page number=%d', [ASheet.pageLayout.StartPageNumber]))
|
||||
else
|
||||
AStrings.Add (' Start page number=automatic');
|
||||
AStrings.Add(Format(' Scaling factor=%.0f%%', [ASheet.PageLayout.ScalingFactor]));
|
||||
AStrings.Add(Format(' Copies=%d', [ASheet.PageLayout.Copies]));
|
||||
s := '';
|
||||
for po in TsPrintOption do
|
||||
if po in ASheet.PageLayout.Options then s := s + '; ' + GetEnumName(typeInfo(TsPrintOption), ord(po));
|
||||
if s <> '' then Delete(s, 1, 2);
|
||||
AStrings.Add(Format(' Options=%s', [s]));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -668,13 +668,39 @@ type
|
||||
cctError : (ErrorValue: TsErrorValue);
|
||||
end;
|
||||
|
||||
TsPageLayout = record
|
||||
LeftMargin: Double; // in Points
|
||||
{
|
||||
TsPaperSize = (psUndefined, psLetter, psLetterSmall, psTabloid, psLedger,
|
||||
psLegal, psStatement, psExecutive, psA3, psA4, psA4small, psA5, psB4, psB5,
|
||||
psFolie, psQuarto, ps10x14, ps11x17, psNote, psEnvelope9, psEnvelope10,
|
||||
psEnvelope11, psEnvelope12, psEnvelope14, psC, psD, psE, psEnvelopeDL,
|
||||
psEnvelopeC5, psEnvelopeC3, psEnvelopeC4, psEnvelopeC6, psEnvelopeC6C5,
|
||||
psB4ISO, psB5ISO, psB6ISO,
|
||||
}
|
||||
|
||||
TsPageOrientation = (spoPortrait, spoLandscape);
|
||||
|
||||
TsPrintOption = (poPrintGridLines, poPrintHeaders, poPrintPagesByRows,
|
||||
poMonochrome, poDraftQuality, poPrintCellComments, poDefaultOrientation,
|
||||
poUseStartPageNumber, poCommentsAtEnd, poHorCentered, poVertCentered);
|
||||
|
||||
TsPrintOptions = set of TsPrintOption;
|
||||
|
||||
TsPageLayout = record // all lengths in mm
|
||||
Orientation: TsPageOrientation;
|
||||
PageWidth: Double; // for "normal" orientation (mostly portrait)
|
||||
PageHeight: Double;
|
||||
LeftMargin: Double;
|
||||
RightMargin: Double;
|
||||
TopMargin: Double;
|
||||
BottomMargin: Double;
|
||||
HeaderDistance: Double;
|
||||
FooterDistance: Double;
|
||||
HeaderMargin: Double;
|
||||
FooterMargin: Double;
|
||||
StartPageNumber: Integer;
|
||||
ScalingFactor: Double; // in percent
|
||||
FitWidthToPages: Integer;
|
||||
FitHeightToPages: Integer;
|
||||
Copies: Integer;
|
||||
Options: TsPrintOptions;
|
||||
end;
|
||||
|
||||
function BuildFormatStringFromSection(const ASection: TsNumFormatSection): String;
|
||||
|
@ -134,17 +134,19 @@ function TryStrToFloatAuto(AText: String; out ANumber: Double;
|
||||
function TryFractionStrToFloat(AText: String; out ANumber: Double;
|
||||
out AMaxDigits: Integer): Boolean;
|
||||
|
||||
function TwipsToPts(AValue: Integer): Single;
|
||||
function PtsToTwips(AValue: Single): Integer;
|
||||
function cmToPts(AValue: Double): Double;
|
||||
function PtsToCm(AValue: Double): Double;
|
||||
function InToPts(AValue: Double): Double;
|
||||
function PtsToIn(AValue: Double): Double;
|
||||
function mmToPts(AValue: Double): Double;
|
||||
function PtsToMM(AValue: Double): Double;
|
||||
function pxToPts(AValue, AScreenPixelsPerInch: Integer): Double;
|
||||
function PtsToPx(AValue: Double; AScreenPixelsPerInch: Integer): Integer;
|
||||
function HTMLLengthStrToPts(AValue: String): Double;
|
||||
function TwipsToPts(AValue: Integer): Single; inline;
|
||||
function PtsToTwips(AValue: Single): Integer; inline;
|
||||
function cmToPts(AValue: Double): Double; inline;
|
||||
function PtsToCm(AValue: Double): Double; inline;
|
||||
function InToMM(AValue: Double): Double; inline;
|
||||
function InToPts(AValue: Double): Double; inline;
|
||||
function PtsToIn(AValue: Double): Double; inline;
|
||||
function mmToPts(AValue: Double): Double; inline;
|
||||
function mmToIn(AValue: Double): Double; inline;
|
||||
function PtsToMM(AValue: Double): Double; inline;
|
||||
function pxToPts(AValue, AScreenPixelsPerInch: Integer): Double; inline;
|
||||
function PtsToPx(AValue: Double; AScreenPixelsPerInch: Integer): Integer; inline;
|
||||
function HTMLLengthStrToPts(AValue: String; DefaultUnits: String = 'pt'): Double;
|
||||
|
||||
function HTMLColorStrToColor(AValue: String): TsColorValue;
|
||||
function ColorToHTMLColorStr(AValue: TsColorValue; AExcelDialect: Boolean = false): String;
|
||||
@ -165,6 +167,7 @@ procedure FixHyperlinkPathDelims(var ATarget: String);
|
||||
procedure InitCell(out ACell: TCell); overload;
|
||||
procedure InitCell(ARow, ACol: Cardinal; out ACell: TCell); overload;
|
||||
procedure InitFormatRecord(out AValue: TsCellFormat);
|
||||
procedure InitPageLayout(out APageLayout: TsPageLayout);
|
||||
|
||||
procedure AppendToStream(AStream: TStream; const AString: String); inline; overload;
|
||||
procedure AppendToStream(AStream: TStream; const AString1, AString2: String); inline; overload;
|
||||
@ -1977,6 +1980,28 @@ begin
|
||||
Result := AValue / 72 * 2.54;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Converts inches to millimeters
|
||||
|
||||
@param AValue Length value in inches
|
||||
@return Value converted to mm
|
||||
-------------------------------------------------------------------------------}
|
||||
function InToMM(AValue: Double): Double;
|
||||
begin
|
||||
Result := AValue * 25.4;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Converts millimeters to inches
|
||||
|
||||
@param AValue Length value in millimeters
|
||||
@return Value converted to inches
|
||||
-------------------------------------------------------------------------------}
|
||||
function mmToIn(AValue: Double): Double;
|
||||
begin
|
||||
Result := AValue / 25.4;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Converts inches to points (72 pts = 1 inch)
|
||||
|
||||
@ -2052,9 +2077,11 @@ end;
|
||||
such as '1.25in'. These unit codes are accepted:
|
||||
'px' (pixels), 'pt' (points), 'in' (inches), 'mm' (millimeters),
|
||||
'cm' (centimeters).
|
||||
@param DefaultUnits String identifying the units to be used if not contained
|
||||
in AValue.
|
||||
@return Extracted length in points
|
||||
-------------------------------------------------------------------------------}
|
||||
function HTMLLengthStrToPts(AValue: String): Double;
|
||||
function HTMLLengthStrToPts(AValue: String; DefaultUnits: String = 'pt'): Double;
|
||||
var
|
||||
units: String;
|
||||
x: Double;
|
||||
@ -2062,10 +2089,11 @@ var
|
||||
begin
|
||||
if (Length(AValue) > 1) and (AValue[Length(AValue)] in ['a'..'z', 'A'..'Z']) then begin
|
||||
units := lowercase(Copy(AValue, Length(AValue)-1, 2));
|
||||
if units = '' then units := DefaultUnits;
|
||||
val(copy(AValue, 1, Length(AValue)-2), x, res);
|
||||
// No hasseling with the decimal point...
|
||||
end else begin
|
||||
units := '';
|
||||
units := DefaultUnits;
|
||||
val(AValue, x, res);
|
||||
end;
|
||||
if res <> 0 then
|
||||
@ -2376,6 +2404,30 @@ begin
|
||||
AValue.NumberFormatIndex := -1; // GENERAL format not contained in NumFormatList
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Initializes the fields of a TsPageLayout record
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure InitPageLayout(out APageLayout: TsPageLayout);
|
||||
begin
|
||||
with APageLayout do begin
|
||||
Orientation := spoPortrait;
|
||||
PageWidth := 210;
|
||||
PageHeight := 297;
|
||||
LeftMargin := InToMM(0.7);
|
||||
RightMargin := InToMM(0.7);
|
||||
TopMargin := InToMM(0.78740157499999996);
|
||||
BottomMargin := InToMM(0.78740157499999996);
|
||||
HeaderMargin := InToMM(0.3);
|
||||
FooterMargin := InToMM(0.3);
|
||||
StartPageNumber := 1;
|
||||
ScalingFactor := 100; // Percent
|
||||
FitWidthToPages := 0; // use as many pages as needed
|
||||
FitHeightToPages := 0;
|
||||
Copies := 1;
|
||||
Options := [];
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Appends a string to a stream
|
||||
|
||||
|
@ -455,27 +455,33 @@ begin
|
||||
|
||||
case RecordType of
|
||||
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
||||
INT_EXCEL_ID_BOF : ;
|
||||
INT_EXCEL_ID_BOOLERROR : ReadBool(AStream);
|
||||
INT_EXCEL_ID_BOTTOMMARGIN: ReadBottomMargin(AStream);
|
||||
INT_EXCEL_ID_CODEPAGE : ReadCodePage(AStream);
|
||||
INT_EXCEL_ID_NOTE : ReadComment(AStream);
|
||||
INT_EXCEL_ID_COLWIDTH : ReadColWidth(AStream);
|
||||
INT_EXCEL_ID_DEFCOLWIDTH : ReadDefColWidth(AStream);
|
||||
INT_EXCEL_ID_EOF : BIFF2EOF := True;
|
||||
INT_EXCEL_ID_FONT : ReadFont(AStream);
|
||||
INT_EXCEL_ID_FONTCOLOR : ReadFontColor(AStream);
|
||||
INT_EXCEL_ID_FORMAT : ReadFormat(AStream);
|
||||
INT_EXCEL_ID_FORMULA : ReadFormula(AStream);
|
||||
INT_EXCEL_ID_INTEGER : ReadInteger(AStream);
|
||||
INT_EXCEL_ID_IXFE : ReadIXFE(AStream);
|
||||
INT_EXCEL_ID_NUMBER : ReadNumber(AStream);
|
||||
INT_EXCEL_ID_LABEL : ReadLabel(AStream);
|
||||
INT_EXCEL_ID_FORMULA : ReadFormula(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
INT_EXCEL_ID_COLWIDTH : ReadColWidth(AStream);
|
||||
INT_EXCEL_ID_DEFCOLWIDTH : ReadDefColWidth(AStream);
|
||||
INT_EXCEL_ID_LEFTMARGIN : ReadLeftMargin(AStream);
|
||||
INT_EXCEL_ID_NOTE : ReadComment(AStream);
|
||||
INT_EXCEL_ID_NUMBER : ReadNumber(AStream);
|
||||
INT_EXCEL_ID_PANE : ReadPane(AStream);
|
||||
INT_EXCEL_ID_PRINTGRID : ReadPrintGridLines(AStream);
|
||||
INT_EXCEL_ID_PRINTHEADERS: ReadPrintHeaders(AStream);
|
||||
INT_EXCEL_ID_RIGHTMARGIN : ReadRightMargin(AStream);
|
||||
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
INT_EXCEL_ID_TOPMARGIN : ReadTopMargin(AStream);
|
||||
INT_EXCEL_ID_DEFROWHEIGHT: ReadDefRowHeight(AStream);
|
||||
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
|
||||
INT_EXCEL_ID_PANE : ReadPane(AStream);
|
||||
INT_EXCEL_ID_XF : ReadXF(AStream);
|
||||
INT_EXCEL_ID_BOF : ;
|
||||
INT_EXCEL_ID_EOF : BIFF2EOF := True;
|
||||
else
|
||||
// nothing
|
||||
end;
|
||||
@ -1229,8 +1235,18 @@ begin
|
||||
raise Exception.Create(rsWorksheetNotFound1);
|
||||
|
||||
WriteBOF(AStream);
|
||||
WriteFonts(AStream);
|
||||
WriteCodePage(AStream, FCodePage);
|
||||
WritePrintHeaders(AStream);
|
||||
WritePrintGridLines(AStream);
|
||||
WriteFonts(AStream);
|
||||
|
||||
// Page settings block
|
||||
WriteLeftMargin(AStream);
|
||||
WriteRightMargin(AStream);
|
||||
WriteTopMargin(AStream);
|
||||
WriteBottomMargin(AStream);
|
||||
// WritePageSetup(AStream); // does not exist in BIFF2
|
||||
|
||||
WriteFormatCount(AStream);
|
||||
WriteNumFormats(AStream);
|
||||
WriteXFRecords(AStream);
|
||||
|
@ -390,25 +390,34 @@ begin
|
||||
|
||||
case RecordType of
|
||||
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
||||
INT_EXCEL_ID_BOF : ;
|
||||
INT_EXCEL_ID_BOOLERROR : ReadBool(AStream);
|
||||
INT_EXCEL_ID_BOTTOMMARGIN : ReadBottomMargin(AStream);
|
||||
INT_EXCEL_ID_COLINFO : ReadColInfo(AStream);
|
||||
INT_EXCEL_ID_DEFCOLWIDTH : ReadDefColWidth(AStream);
|
||||
INT_EXCEL_ID_EOF : SectionEOF := True;
|
||||
INT_EXCEL_ID_FORMULA : ReadFormula(AStream);
|
||||
INT_EXCEL_ID_HCENTER : ReadHCENTER(AStream);
|
||||
INT_EXCEL_ID_LABEL : ReadLabel(AStream);
|
||||
INT_EXCEL_ID_LEFTMARGIN : ReadLeftMargin(AStream);
|
||||
INT_EXCEL_ID_MULBLANK : ReadMulBlank(AStream);
|
||||
INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream);
|
||||
INT_EXCEL_ID_NOTE : ReadComment(AStream);
|
||||
INT_EXCEL_ID_NUMBER : ReadNumber(AStream);
|
||||
INT_EXCEL_ID_LABEL : ReadLabel(AStream);
|
||||
INT_EXCEL_ID_RSTRING : ReadRichString(AStream); //(RSTRING) This record stores a formatted text cell (Rich-Text). In BIFF8 it is usually replaced by the LABELSST record. Excel still uses this record, if it copies formatted text cells to the clipboard.
|
||||
INT_EXCEL_ID_RK : ReadRKValue(AStream); //(RK) This record represents a cell that contains an RK value (encoded integer or floating-point value). If a floating-point value cannot be encoded to an RK value, a NUMBER record will be written. This record replaces the record INTEGER written in BIFF2.
|
||||
INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream);
|
||||
INT_EXCEL_ID_COLINFO : ReadColInfo(AStream);
|
||||
INT_EXCEL_ID_STANDARDWIDTH : ReadStandardWidth(AStream, FWorksheet);
|
||||
INT_EXCEL_ID_DEFCOLWIDTH : ReadDefColWidth(AStream);
|
||||
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
|
||||
INT_EXCEL_ID_FORMULA : ReadFormula(AStream);
|
||||
INT_EXCEL_ID_SHAREDFMLA : ReadSharedFormula(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
|
||||
INT_EXCEL_ID_PANE : ReadPane(AStream);
|
||||
INT_EXCEL_ID_BOF : ;
|
||||
INT_EXCEL_ID_EOF : SectionEOF := True;
|
||||
INT_EXCEL_ID_PAGESETUP : ReadPageSetup(AStream);
|
||||
INT_EXCEL_ID_PRINTGRID : ReadPrintGridLines(AStream);
|
||||
INT_EXCEL_ID_PRINTHEADERS : ReadPrintHeaders(AStream);
|
||||
INT_EXCEL_ID_RIGHTMARGIN : ReadRightMargin(AStream);
|
||||
INT_EXCEL_ID_RK : ReadRKValue(AStream); //(RK) This record represents a cell that contains an RK value (encoded integer or floating-point value). If a floating-point value cannot be encoded to an RK value, a NUMBER record will be written. This record replaces the record INTEGER written in BIFF2.
|
||||
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
|
||||
INT_EXCEL_ID_RSTRING : ReadRichString(AStream); //(RSTRING) This record stores a formatted text cell (Rich-Text). In BIFF8 it is usually replaced by the LABELSST record. Excel still uses this record, if it copies formatted text cells to the clipboard.
|
||||
INT_EXCEL_ID_SHAREDFMLA : ReadSharedFormula(AStream);
|
||||
INT_EXCEL_ID_STANDARDWIDTH : ReadStandardWidth(AStream, FWorksheet);
|
||||
INT_EXCEL_ID_TOPMARGIN : ReadTopMargin(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
INT_EXCEL_ID_VCENTER : ReadVCENTER(AStream);
|
||||
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
|
||||
|
||||
{$IFDEF FPSPREADDEBUG} // Only write out if debugging
|
||||
else
|
||||
@ -1030,9 +1039,19 @@ begin
|
||||
AStream.Position := CurrentPos;
|
||||
|
||||
WriteBOF(AStream, INT_BOF_SHEET);
|
||||
|
||||
WriteIndex(AStream);
|
||||
// WritePageSetup(AStream);
|
||||
WritePrintHeaders(AStream);
|
||||
WritePrintGridLines(AStream);
|
||||
|
||||
// Page settings block
|
||||
WriteHCenter(AStream);
|
||||
WriteVCenter(AStream);
|
||||
WriteLeftMargin(AStream);
|
||||
WriteRightMargin(AStream);
|
||||
WriteTopMargin(AStream);
|
||||
WriteBottomMargin(AStream);
|
||||
WritePageSetup(AStream);
|
||||
|
||||
WriteColInfos(AStream, FWorksheet);
|
||||
WriteDimensions(AStream, FWorksheet);
|
||||
WriteWindow2(AStream, FWorksheet);
|
||||
|
@ -120,6 +120,7 @@ type
|
||||
|
||||
TsSpreadBIFF8Writer = class(TsSpreadBIFFWriter)
|
||||
protected
|
||||
function GetPrintOptions: Word; override;
|
||||
{ Record writing methods }
|
||||
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
||||
function WriteBoundsheet(AStream: TStream; ASheetName: string): Int64;
|
||||
@ -675,39 +676,51 @@ begin
|
||||
|
||||
case RecordType of
|
||||
|
||||
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
||||
INT_EXCEL_ID_BOOLERROR : ReadBool(AStream);
|
||||
INT_EXCEL_ID_CONTINUE : ReadCONTINUE(AStream);
|
||||
INT_EXCEL_ID_FORMULA : ReadFormula(AStream);
|
||||
INT_EXCEL_ID_HYPERLINK : ReadHyperlink(AStream);
|
||||
INT_EXCEL_ID_HLINKTOOLTIP: ReadHyperlinkToolTip(AStream);
|
||||
INT_EXCEL_ID_LABEL : ReadLabel(AStream);
|
||||
INT_EXCEL_ID_MULBLANK : ReadMulBlank(AStream);
|
||||
INT_EXCEL_ID_NOTE : ReadNOTE(AStream);
|
||||
INT_EXCEL_ID_NUMBER : ReadNumber(AStream);
|
||||
INT_EXCEL_ID_OBJ : ReadOBJ(AStream);
|
||||
INT_EXCEL_ID_SHAREDFMLA : ReadSharedFormula(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
INT_EXCEL_ID_TXO : ReadTXO(AStream);
|
||||
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
||||
INT_EXCEL_ID_BOF : ;
|
||||
INT_EXCEL_ID_BOOLERROR : ReadBool(AStream);
|
||||
INT_EXCEL_ID_BOTTOMMARGIN : ReadBottomMargin(AStream);
|
||||
INT_EXCEL_ID_COLINFO : ReadColInfo(AStream);
|
||||
INT_EXCEL_ID_CONTINUE : ReadCONTINUE(AStream);
|
||||
INT_EXCEL_ID_DEFCOLWIDTH : ReadDefColWidth(AStream);
|
||||
INT_EXCEL_ID_EOF : SectionEOF := True;
|
||||
INT_EXCEL_ID_FORMULA : ReadFormula(AStream);
|
||||
INT_EXCEL_ID_HCENTER : ReadHCENTER(AStream);
|
||||
INT_EXCEL_ID_HLINKTOOLTIP : ReadHyperlinkToolTip(AStream);
|
||||
INT_EXCEL_ID_HYPERLINK : ReadHyperlink(AStream);
|
||||
INT_EXCEL_ID_LABEL : ReadLabel(AStream);
|
||||
INT_EXCEL_ID_LABELSST : ReadLabelSST(AStream);
|
||||
INT_EXCEL_ID_LEFTMARGIN : ReadLeftMargin(AStream);
|
||||
INT_EXCEL_ID_MERGEDCELLS : ReadMergedCells(AStream);
|
||||
INT_EXCEL_ID_MULBLANK : ReadMulBlank(AStream);
|
||||
INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream);
|
||||
INT_EXCEL_ID_NOTE : ReadNOTE(AStream);
|
||||
INT_EXCEL_ID_NUMBER : ReadNumber(AStream);
|
||||
INT_EXCEL_ID_OBJ : ReadOBJ(AStream);
|
||||
INT_EXCEL_ID_PAGESETUP : ReadPageSetup(AStream);
|
||||
INT_EXCEL_ID_PANE : ReadPane(AStream);
|
||||
INT_EXCEL_ID_PRINTGRID : ReadPrintGridLines(AStream);
|
||||
INT_EXCEL_ID_PRINTHEADERS : ReadPrintHeaders(AStream);
|
||||
INT_EXCEL_ID_RIGHTMARGIN : ReadRightMargin(AStream);
|
||||
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
|
||||
|
||||
//(RSTRING) This record stores a formatted text cell (Rich-Text).
|
||||
// In BIFF8 it is usually replaced by the LABELSST record. Excel still
|
||||
// uses this record, if it copies formatted text cells to the clipboard.
|
||||
INT_EXCEL_ID_RSTRING : ReadRichString(AStream);
|
||||
INT_EXCEL_ID_RSTRING : ReadRichString(AStream);
|
||||
|
||||
// (RK) This record represents a cell that contains an RK value
|
||||
// (encoded integer or floating-point value). If a floating-point
|
||||
// value cannot be encoded to an RK value, a NUMBER record will be written.
|
||||
// This record replaces the record INTEGER written in BIFF2.
|
||||
INT_EXCEL_ID_RK : ReadRKValue(AStream);
|
||||
INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream);
|
||||
INT_EXCEL_ID_LABELSST : ReadLabelSST(AStream); //BIFF8 only
|
||||
INT_EXCEL_ID_DEFCOLWIDTH : ReadDefColWidth(AStream);
|
||||
INT_EXCEL_ID_COLINFO : ReadColInfo(AStream);
|
||||
INT_EXCEL_ID_MERGEDCELLS : ReadMergedCells(AStream);
|
||||
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
|
||||
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
|
||||
INT_EXCEL_ID_PANE : ReadPane(AStream);
|
||||
INT_EXCEL_ID_BOF : ;
|
||||
INT_EXCEL_ID_EOF : SectionEOF := True;
|
||||
INT_EXCEL_ID_RK : ReadRKValue(AStream);
|
||||
|
||||
INT_EXCEL_ID_SHAREDFMLA : ReadSharedFormula(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
INT_EXCEL_ID_TOPMARGIN : ReadTopMargin(AStream);
|
||||
INT_EXCEL_ID_TXO : ReadTXO(AStream);
|
||||
INT_EXCEL_ID_VCENTER : ReadVCENTER(AStream);
|
||||
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
|
||||
else
|
||||
// nothing
|
||||
end;
|
||||
@ -1614,6 +1627,17 @@ begin
|
||||
FDateMode := Excel8Settings.DateMode;
|
||||
end;
|
||||
|
||||
function TsSpreadBIFF8Writer.GetPrintOptions: Word;
|
||||
Begin
|
||||
Result := inherited GetPrintOptions;
|
||||
{ The following flags are valid for BIFF8 only:
|
||||
Bit 9: 0 = Print notes as displayed; 1 = Print notes at end of sheet
|
||||
Bit 11-10: 00 = Print errors as displayed; 1 = Do not print errors
|
||||
2 = Print errors as “--”; 3 = Print errors as “#N/A” }
|
||||
if poCommentsAtEnd in FWorksheet.PageLayout.Options then
|
||||
Result := Result or $0200;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes an Excel BIFF8 file to the disc
|
||||
|
||||
@ -1695,8 +1719,20 @@ begin
|
||||
|
||||
WriteBOF(AStream, INT_BOF_SHEET);
|
||||
WriteIndex(AStream);
|
||||
WritePrintHeaders(AStream);
|
||||
WritePrintGridLines(AStream);
|
||||
|
||||
//WriteSheetPR(AStream);
|
||||
// WritePageSetup(AStream);
|
||||
|
||||
// Page setting block
|
||||
WriteHCenter(AStream);
|
||||
WriteVCenter(AStream);
|
||||
WriteLeftMargin(AStream);
|
||||
WriteRightMargin(AStream);
|
||||
WriteTopMargin(AStream);
|
||||
WriteBottomMargin(AStream);
|
||||
WritePageSetup(AStream);
|
||||
|
||||
WriteColInfos(AStream, FWorksheet);
|
||||
WriteDimensions(AStream, FWorksheet);
|
||||
//WriteRowAndCellBlock(AStream, sheet);
|
||||
|
@ -20,6 +20,12 @@ const
|
||||
INT_EXCEL_ID_NOTE = $001C;
|
||||
INT_EXCEL_ID_SELECTION = $001D;
|
||||
INT_EXCEL_ID_DATEMODE = $0022;
|
||||
INT_EXCEL_ID_LEFTMARGIN = $0026;
|
||||
INT_EXCEL_ID_RIGHTMARGIN = $0027;
|
||||
INT_EXCEL_ID_TOPMARGIN = $0028;
|
||||
INT_EXCEL_ID_BOTTOMMARGIN= $0029;
|
||||
INT_EXCEL_ID_PRINTHEADERS= $002A;
|
||||
INT_EXCEL_ID_PRINTGRID = $002B;
|
||||
INT_EXCEL_ID_CONTINUE = $003C;
|
||||
INT_EXCEL_ID_WINDOW1 = $003D;
|
||||
INT_EXCEL_ID_PANE = $0041;
|
||||
@ -33,6 +39,8 @@ const
|
||||
{ RECORD IDs which did not change across version 3-8}
|
||||
INT_EXCEL_ID_COLINFO = $007D; // does not exist in BIFF2
|
||||
INT_EXCEL_ID_SHEETPR = $0081; // does not exist in BIFF2
|
||||
INT_EXCEL_ID_HCENTER = $0083; // does not exist in BIFF2
|
||||
INT_EXCEL_ID_VCENTER = $0084; // does not exist in BIFF2
|
||||
INT_EXCEL_ID_COUNTRY = $008C; // does not exist in BIFF2
|
||||
INT_EXCEL_ID_PALETTE = $0092; // does not exist in BIFF2
|
||||
INT_EXCEL_ID_DIMENSIONS = $0200; // BIFF2: $0000
|
||||
@ -215,6 +223,100 @@ const
|
||||
{ Index of last built-in XF format record }
|
||||
LAST_BUILTIN_XF = 15;
|
||||
|
||||
PAPER_SIZES: array[0..90] of array[0..1] of Double = ( // Dimensions in mm
|
||||
( 0.0 , 0.0 ), // 0 - undefined
|
||||
(2.54* 8.5 , 11.0 *2.54), // 1 - Letter
|
||||
(2.54* 8.5 , 11.0 *2.54), // 2 - Letter small
|
||||
(2.54* 11.0 , 17.0 *2.54), // 3 - Tabloid
|
||||
(2.54* 17.0 , 11.0 *2.54), // 4 - Ledger
|
||||
(2.54* 8.5 , 14.0 *2.54), // 5 - Legal
|
||||
(2.54* 5.5 , 8.5 *2.54), // 6 - Statement
|
||||
(2.54* 7.25 , 10.5 *2.54), // 7 - Executive
|
||||
( 297.0 , 420.0 ), // 8 - A3
|
||||
( 210.0 , 297.0 ), // 9 - A4
|
||||
( 210.0 , 297.0 ), // 10 - A4 small
|
||||
( 148.0 , 210.0 ), // 11 - A5
|
||||
( 257.0 , 364.0 ), // 12 - B4 (JIS)
|
||||
( 182.0 , 257.0 ), // 13 - B5 (JIS)
|
||||
(2.54* 8.5 , 13.0 *2.54), // 14 - Folie
|
||||
( 215.0 , 275.0 ), // 15 - Quarto
|
||||
(2.54* 10.0 , 14.0 *2.54), // 16 - 10x14
|
||||
(2.54* 11.0 , 17.0 *2.54), // 17 - 11x17
|
||||
(2.54* 8.5 , 11.0 *2.54), // 18 - Note
|
||||
(2.54* 3.875, 8.875*2.54), // 19 - Envelope #9
|
||||
(2.54* 4.125, 9.5 *2.54), // 20 - Envelope #10
|
||||
(2.54* 4.5 , 10.375*2.54), // 21 - Envelope #11
|
||||
(2.54* 4.75 , 11.0 *2.54), // 22 - Envelope #12
|
||||
(2.54* 5.0 , 11.5 *2.54), // 23 - Envelope #14
|
||||
(2.54* 17.0 , 22.0 *2.54), // 24 - C
|
||||
(2.54* 22.0 , 34.0 *2.54), // 25 - D
|
||||
(2.54* 34.0 , 44.0 *2.54), // 26 - E
|
||||
( 110.0 , 220.0 ), // 27 - Envelope DL
|
||||
( 162.0 , 229.0 ), // 28 - Envelope C5
|
||||
( 324.0 , 458.0 ), // 29 - Envelope C3
|
||||
( 229.0 , 324.0 ), // 30 - Envelope C4
|
||||
( 114.0 , 162.0 ), // 31 - Envelope C6
|
||||
( 114.0 , 229.0 ), // 32 - Envelope C6/C5
|
||||
( 250.0 , 353.0 ), // 33 - B4 (ISO)
|
||||
( 176.0 , 250.0 ), // 34 - B5 (ISO)
|
||||
( 125.0 , 176.0 ), // 35 - B6 (ISO)
|
||||
( 110.0 , 230.0 ), // 36 - Envelope Italy
|
||||
(2.54* 3.875, 7.5 *2.54), // 37 - Envelope Monarch
|
||||
(2.54* 3.625, 6.5 *2.54), // 38 - 6 3/4 Envelope
|
||||
(2.54* 14.875, 11.0 *2.54), // 39 - US Standard Fanfold
|
||||
(2.54* 8.5 , 12.0 *2.54), // 40 - German Std Fanfold
|
||||
(2.54* 8.5 , 13.0 *2.54), // 41 - German Legal Fanfold
|
||||
( 250.0 , 353.0 ), // 42 - B4 (ISO)
|
||||
( 100.0 , 148.0 ), // 43 - Japanese Postcard
|
||||
(2.54* 9.0 , 11.0 *2.54), // 44 - 9x11
|
||||
(2.54* 10.0 , 11.0 *2.54), // 45 - 10x11
|
||||
(2.54* 15.0 , 11.0 *2.54), // 46 - 15x11
|
||||
( 220.0 , 220.0 ), // 47 - Envelope Invite
|
||||
( 0.0 , 0.0 ), // 48 - undefined
|
||||
( 0.0 , 0.0 ), // 49 - undefined
|
||||
(2.54* 9.5 , 11.0 *2.54), // 50 - Letter Extra
|
||||
(2.54* 9.5 , 15.0 *2.54), // 51 - Legal Extra
|
||||
(2.54* 11.6875, 18.0 *2.54), // 52 - Tabloid Extra
|
||||
( 235.0 , 322.0 ), // 53 - A4 Extra
|
||||
(2.54* 8.5 , 11.0 *2.54), // 54 - Letter Transverse
|
||||
( 210.0 , 297.0 ), // 55 - A4 Transverse
|
||||
(2.54* 9.5 , 11.0 *2.54), // 56 - Letter Extra Transverse
|
||||
( 227.0 , 356.0 ), // 57 - Super A/A4
|
||||
( 305.0 , 487.0 ), // 58 - Super B/B4
|
||||
(2.54* 8.5 , 12.6875*2.54), // 59 - Letter plus
|
||||
( 210.0 , 330.0 ), // 60 - A4 plus
|
||||
( 148.0 , 210.0 ), // 61 - A5 transverse
|
||||
( 182.0 , 257.0 ), // 62 - B5 (JIS) transverse
|
||||
( 322.0 , 445.0 ), // 63 - A3 Extra
|
||||
( 174.0 , 235.0 ), // 64 - A5 Extra
|
||||
( 201.0 , 276.0 ), // 65 - B5 (ISO) Extra
|
||||
( 420.0 , 594.0 ), // 66 - A2
|
||||
( 297.0 , 420.0 ), // 67 - A3 Transverse
|
||||
( 322.0 , 445.0 ), // 68 - A3 Extra Transverse
|
||||
( 200.0 , 148.0 ), // 69 - Double Japanese Postcard
|
||||
( 105.0 , 148.0 ), // 70 - A6
|
||||
( 0.0 , 0.0 ), // 71 - undefined
|
||||
( 0.0 , 0.0 ), // 72 - undefined
|
||||
( 0.0 , 0.0 ), // 73 - undefined
|
||||
( 0.0 , 0.0 ), // 74 - undefined
|
||||
(2.54* 11.0 , 8.5 *2.54), // 75 - Letter rotated
|
||||
( 420.0 , 297.0 ), // 76 - A3 rotated
|
||||
( 297.0 , 210.0 ), // 77 - A4 rotated
|
||||
( 210.0 , 148.0 ), // 78 - A5 rotated
|
||||
( 364.0 , 257.0 ), // 79 - B4 (JIS) rotated
|
||||
( 257.0 , 182.0 ), // 80 - B5 (JIS) rotated
|
||||
( 148.0 , 100.0 ), // 81 - Japanese Postcard rotated
|
||||
( 148.0 , 200.0 ), // 82 - Double Japanese Postcard rotated
|
||||
( 148.0 , 105.0 ), // 83 - A6 rotated
|
||||
( 0.0 , 0.0 ), // 84 - undefined
|
||||
( 0.0 , 0.0 ), // 85 - undefined
|
||||
( 0.0 , 0.0 ), // 86 - undefined
|
||||
( 0.0 , 0.0 ), // 87 - undefined
|
||||
( 128.0 , 182.0 ), // 88 - B6 (JIS)
|
||||
( 182.0 , 128.0 ), // 89 - B6 (JIS) rotated
|
||||
(2.54* 12.0 , 11.0 *2.54) // 90 - 12x11
|
||||
);
|
||||
|
||||
type
|
||||
TDateMode=(dm1900,dm1904); //DATEMODE values, 5.28
|
||||
|
||||
@ -263,6 +365,7 @@ type
|
||||
// Read a blank cell
|
||||
procedure ReadBlank(AStream: TStream); override;
|
||||
procedure ReadBool(AStream: TStream); override;
|
||||
procedure ReadBottomMargin(AStream: TStream);
|
||||
procedure ReadCodePage(AStream: TStream);
|
||||
// Read column info
|
||||
procedure ReadColInfo(const AStream: TStream);
|
||||
@ -278,6 +381,8 @@ type
|
||||
procedure ReadFormat(AStream: TStream); virtual;
|
||||
// Read FORMULA record
|
||||
procedure ReadFormula(AStream: TStream); override;
|
||||
procedure ReadHCENTER(AStream: TStream);
|
||||
procedure ReadLeftMargin(AStream: TStream);
|
||||
// Read multiple blank cells
|
||||
procedure ReadMulBlank(AStream: TStream);
|
||||
// Read multiple RK cells
|
||||
@ -286,8 +391,13 @@ type
|
||||
procedure ReadNumber(AStream: TStream); override;
|
||||
// Read palette
|
||||
procedure ReadPalette(AStream: TStream);
|
||||
// Read page setup
|
||||
procedure ReadPageSetup(AStream: TStream);
|
||||
// Read PANE record
|
||||
procedure ReadPane(AStream: TStream);
|
||||
procedure ReadPrintGridLines(AStream: TStream);
|
||||
procedure ReadPrintHeaders(AStream: TStream);
|
||||
procedure ReadRightMargin(AStream: TStream);
|
||||
// Read an RK value cell
|
||||
procedure ReadRKValue(AStream: TStream);
|
||||
// Read the row, column, and XF index at the current stream position
|
||||
@ -310,11 +420,13 @@ type
|
||||
ASharedFormulaBase: PCell = nil): Boolean;
|
||||
function ReadRPNTokenArraySize(AStream: TStream): word; virtual;
|
||||
procedure ReadSharedFormula(AStream: TStream);
|
||||
procedure ReadTopMargin(AStream: TStream);
|
||||
|
||||
// Helper function for reading a string with 8-bit length
|
||||
function ReadString_8bitLen(AStream: TStream): String; virtual;
|
||||
// Read STRING record (result of string formula)
|
||||
procedure ReadStringRecord(AStream: TStream); virtual;
|
||||
procedure ReadVCENTER(AStream: TStream);
|
||||
// Read WINDOW2 record (gridlines, sheet headers)
|
||||
procedure ReadWindow2(AStream: TStream); virtual;
|
||||
|
||||
@ -335,6 +447,7 @@ type
|
||||
function FixColor(AColor: TsColor): TsColor; override;
|
||||
function GetLastRowIndex(AWorksheet: TsWorksheet): Integer;
|
||||
function GetLastColIndex(AWorksheet: TsWorksheet): Word;
|
||||
function GetPrintOptions: Word; virtual;
|
||||
|
||||
// Helper function for writing the BIFF header
|
||||
procedure WriteBIFFHeader(AStream: TStream; ARecID, ARecSize: Word);
|
||||
@ -347,6 +460,8 @@ type
|
||||
// Write out BOOLEAN cell record
|
||||
procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
||||
const AValue: Boolean; ACell: PCell); override;
|
||||
// Writes out bottom page margin for printing
|
||||
procedure WriteBottomMargin(AStream: TStream);
|
||||
// Writes out used codepage for character encoding
|
||||
procedure WriteCodePage(AStream: TStream; ACodePage: String); virtual;
|
||||
// Writes out column info(s)
|
||||
@ -365,6 +480,9 @@ type
|
||||
// Writes out a FORMULA record; formula is stored in cell already
|
||||
procedure WriteFormula(AStream: TStream; const ARow, ACol: Cardinal;
|
||||
ACell: PCell); override;
|
||||
procedure WriteHCenter(AStream: TStream);
|
||||
// Writes out left page margin for printing
|
||||
procedure WriteLeftMargin(AStream: TStream);
|
||||
// Writes out a FORMAT record
|
||||
procedure WriteNumFormat(AStream: TStream; ANumFormatStr: String;
|
||||
ANumFormatIndex: Integer); virtual;
|
||||
@ -379,6 +497,11 @@ type
|
||||
// Writes out a PANE record
|
||||
procedure WritePane(AStream: TStream; ASheet: TsWorksheet; IsBiff58: Boolean;
|
||||
out ActivePane: Byte);
|
||||
// Writes out whether grid lines are printed
|
||||
procedure WritePrintGridLines(AStream: TStream);
|
||||
procedure WritePrintHeaders(AStream: TStream);
|
||||
// Writes out right page margin for printing
|
||||
procedure WriteRightMargin(AStream: TStream);
|
||||
// Writes out a ROW record
|
||||
procedure WriteRow(AStream: TStream; ASheet: TsWorksheet;
|
||||
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow); virtual;
|
||||
@ -414,6 +537,9 @@ type
|
||||
*)
|
||||
procedure WriteSheetPR(AStream: TStream);
|
||||
procedure WriteStringRecord(AStream: TStream; AString: String); virtual;
|
||||
// Writes out the top page margin used when printing
|
||||
procedure WriteTopMargin(AStream: TStream);
|
||||
procedure WriteVCenter(AStream: TStream);
|
||||
// Writes cell content received by workbook in OnNeedCellData event
|
||||
procedure WriteVirtualCells(AStream: TStream);
|
||||
// Writes out a WINDOW1 record
|
||||
@ -510,6 +636,7 @@ type
|
||||
TextLen: Word;
|
||||
end;
|
||||
|
||||
|
||||
function ConvertExcelDateTimeToDateTime(const AExcelDateNum: Double;
|
||||
ADateMode: TDateMode): TDateTime;
|
||||
begin
|
||||
@ -851,6 +978,18 @@ begin
|
||||
Workbook.OnReadCellData(Workbook, r, c, cell);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the bottom page margin of the current worksheet (for printing).
|
||||
The file value is in inches.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadBottomMargin(AStream: TStream);
|
||||
var
|
||||
dbl: Double;
|
||||
begin
|
||||
AStream.ReadBuffer(dbl, SizeOf(dbl));
|
||||
FWorksheet.PageLayout.BottomMargin := InToMM(dbl);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the code page used in the xls file
|
||||
In BIFF8 it seams to always use the UTF-16 codepage
|
||||
@ -1141,6 +1280,30 @@ begin
|
||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads whether the page is to be centered horizontally for printing
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadHCENTER(AStream: TStream);
|
||||
var
|
||||
w: word;
|
||||
begin
|
||||
w := WordLEToN(AStream.ReadWord);
|
||||
if w = 1 then Include(FWorksheet.PageLayout.Options, poHorCentered);
|
||||
end;
|
||||
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the left page margin of the current worksheet (for printing).
|
||||
The file value is in inches.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadLeftMargin(AStream: TStream);
|
||||
var
|
||||
dbl: Double;
|
||||
begin
|
||||
AStream.ReadBuffer(dbl, SizeOf(dbl));
|
||||
FWorksheet.PageLayout.LeftMargin := InToMM(dbl);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads multiple blank cell records
|
||||
Valid for BIFF5 and BIFF8 (does not exist before)
|
||||
@ -1294,6 +1457,72 @@ begin
|
||||
FPaletteFound := true;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the page setup record containing some parameters for printing
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadPageSetup(AStream: TStream);
|
||||
var
|
||||
w: Word;
|
||||
dbl: Double;
|
||||
begin
|
||||
// Paper size
|
||||
w := WordLEToN(AStream.ReadWord);
|
||||
if (w >= 0) and (w <= High(PAPER_SIZES)) then
|
||||
begin
|
||||
FWorksheet.PageLayout.PageWidth := PAPER_SIZES[w, 0];
|
||||
FWorksheet.PageLayout.PageHeight := PAPER_SIZES[w, 1];
|
||||
end;
|
||||
|
||||
// Scaling factor in percent
|
||||
FWorksheet.PageLayout.ScalingFactor := WordLEToN(AStream.ReadWord);
|
||||
|
||||
// Start page number
|
||||
FWorksheet.PageLayout.StartPageNumber := WordLEToN(AStream.ReadWord);
|
||||
|
||||
// Fit worksheet width to this number of pages (0 = use as many as neede)
|
||||
FWorksheet.PageLayout.FitWidthToPages := WordLEToN(AStream.ReadWord);
|
||||
|
||||
// Fit worksheet height to this number of pages (0 = use as many as needed)
|
||||
FWorksheet.PageLayout.FitHeightToPages := WordLEToN(AStream.ReadWord);
|
||||
|
||||
// Option flags
|
||||
w := WordLEToN(AStream.ReadWord);
|
||||
if w and $0001 <> 0 then
|
||||
Include(FWorksheet.pageLayout.Options, poPrintPagesByRows);
|
||||
if w and $0002 <> 0 then
|
||||
FWorksheet.PageLayout.Orientation := spoPortrait else
|
||||
FWorksheet.PageLayout.Orientation := spoLandscape;
|
||||
if w and $0008 <> 0 then
|
||||
Include(FWorksheet.PageLayout.Options, poMonochrome);
|
||||
if w and $0010 <> 0 then
|
||||
Include(FWorksheet.PageLayout.Options, poDraftQuality);
|
||||
if w and $0020 <> 0 then
|
||||
Include(FWorksheet.PageLayout.Options, poPrintCellComments);
|
||||
if w and $0040 <> 0 then
|
||||
Include(FWorksheet.PageLayout.Options, poDefaultOrientation);
|
||||
if w and $0080 <> 0 then
|
||||
Include(FWorksheet.PageLayout.Options, poUseStartPageNumber);
|
||||
if w and $0200 <> 0 then
|
||||
Include(FWorksheet.Pagelayout.Options, poCommentsAtEnd);
|
||||
|
||||
// Print resolution in dpi -- ignoried
|
||||
w := WordLEToN(AStream.ReadWord);
|
||||
|
||||
// Vertical print resolution in dpi -- ignored
|
||||
w := WordLEToN(AStream.ReadWord);
|
||||
|
||||
// Header margin
|
||||
AStream.ReadBuffer(dbl, SizeOf(dbl));
|
||||
FWorksheet.PageLayout.HeaderMargin := InToMM(dbl);
|
||||
|
||||
// Footer margin
|
||||
AStream.ReadBuffer(dbl, SizeOf(dbl));
|
||||
FWorksheet.PageLayout.FooterMargin := InToMM(dbl);
|
||||
|
||||
// Number of copies
|
||||
FWorksheet.PageLayout.Copies := WordLEToN(AStream.ReadWord);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads pane sizes
|
||||
Valid for all BIFF versions
|
||||
@ -1321,6 +1550,30 @@ begin
|
||||
[9] 1 Not used (BIFF5-BIFF8 only, not written in BIFF2-BIFF4) }
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads whether the gridlines are printed or not
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadPrintGridLines(AStream: TStream);
|
||||
var
|
||||
w: Word;
|
||||
begin
|
||||
w := WordLEToN(AStream.ReadWord);
|
||||
if w = 1 then
|
||||
Include(FWorksheet.PageLayout.Options, poPrintGridLines);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads whether the spreadsheet row/column headers are printed or not
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadPrintHeaders(AStream: TStream);
|
||||
var
|
||||
w: Word;
|
||||
begin
|
||||
w := WordLEToN(AStream.ReadWord);
|
||||
if w = 1 then
|
||||
Include(FWorksheet.PageLayout.Options , poPrintHeaders);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the row, column and xf index
|
||||
NOT VALID for BIFF2
|
||||
@ -1336,6 +1589,18 @@ begin
|
||||
AXF := WordLEtoN(AStream.ReadWord);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the right page margin of the current worksheet (for printing).
|
||||
The file value is in inches.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadRightMargin(AStream: TStream);
|
||||
var
|
||||
dbl: Double;
|
||||
begin
|
||||
AStream.ReadBuffer(dbl, SizeOf(dbl));
|
||||
FWorksheet.PageLayout.RightMargin := InToMM(dbl);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads an RK value cell from the stream
|
||||
Valid since BIFF3.
|
||||
@ -1799,6 +2064,29 @@ begin
|
||||
Unused(AStream);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the top page margin of the current worksheet (for printing).
|
||||
The file value is in inches.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadTopMargin(AStream: TStream);
|
||||
var
|
||||
dbl: Double;
|
||||
begin
|
||||
AStream.ReadBuffer(dbl, SizeOf(dbl));
|
||||
FWorksheet.PageLayout.TopMargin := InToMM(dbl);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads whether the page is to be centered vertically for printing
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadVCENTER(AStream: TStream);
|
||||
var
|
||||
w: word;
|
||||
begin
|
||||
w := WordLEToN(AStream.ReadWord);
|
||||
if w = 1 then Include(FWorksheet.PageLayout.Options, poVertCentered);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the WINDOW2 record containing information like "show grid lines",
|
||||
"show sheet headers", "panes are frozen", etc.
|
||||
@ -1893,6 +2181,46 @@ begin
|
||||
Result := AWorksheet.GetLastColIndex;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Converts the Options of the worksheet's PageLayout to the bitmap required
|
||||
by the PageSetup record
|
||||
Is overridden by BIFF8 which uses more bits. Not used by BIFF2.
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsSpreadBIFFWriter.GetPrintOptions: Word;
|
||||
begin
|
||||
{ Options:
|
||||
Bit 0: 0 = Print pages in columns; 1 = Print pages in rows
|
||||
Bit 1: 0 = Landscape; 1 = Portrait
|
||||
Bit 2: 1 = Paper size, scaling factor, paper orientation (portrait/landscape),
|
||||
print resolution and number of copies are not initialised
|
||||
Bit 3: 0 = Print coloured; 1 = Print black and white
|
||||
Bit 4: 0 = Default print quality; 1 = Draft quality
|
||||
Bit 5: 0 = Do not print cell notes; 1 = Print cell notes
|
||||
Bit 6: 0 = Use paper orientation (portrait/landscape) flag above
|
||||
1 = Use default paper orientation (landscape for chart sheets, portrait otherwise)
|
||||
Bit 7: 0 = Automatic page numbers; 1 = Use start page number above
|
||||
|
||||
The following flags are valid for BIFF8 only:
|
||||
Bit 9: 0 = Print notes as displayed; 1 = Print notes at end of sheet
|
||||
Bit 11-10: 00 = Print errors as displayed; 1 = Do not print errors
|
||||
2 = Print errors as “--”; 3 = Print errors as “#N/A” }
|
||||
Result := 0;
|
||||
if poPrintPagesByRows in FWorksheet.PageLayout.Options then
|
||||
Result := Result or $0001;
|
||||
if FWorksheet.PageLayout.Orientation = spoPortrait then
|
||||
Result := Result or $0002;
|
||||
if poMonochrome in FWorksheet.PageLayout.Options then
|
||||
Result := Result or $0008;
|
||||
if poDraftQuality in FWorksheet.PageLayout.Options then
|
||||
Result := Result or $0010;
|
||||
if poPrintCellComments in FWorksheet.PageLayout.Options then
|
||||
Result := Result or $0020;
|
||||
if poDefaultOrientation in FWorksheet.PageLayout.Options then
|
||||
Result := Result or $0040;
|
||||
if poUseStartPageNumber in FWorksheet.PageLayout.Options then
|
||||
Result := Result or $0080;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes the BIFF record header consisting of the record ID and the size of
|
||||
data to be written immediately afterwards.
|
||||
@ -1970,6 +2298,21 @@ begin
|
||||
AStream.WriteBuffer(rec, SizeOf(rec));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Write the bottom margin of the printed page (in inches)
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WriteBottomMargin(AStream: TStream);
|
||||
var
|
||||
dbl: double;
|
||||
begin
|
||||
{ BIFF record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_BOTTOMMARGIN, SizeOf(Double));
|
||||
|
||||
{ Page margin value, written in inches }
|
||||
dbl := mmToIn(FWorksheet.PageLayout.BottomMargin);
|
||||
AStream.WriteBuffer(dbl, SizeOf(dbl));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
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
|
||||
@ -2192,6 +2535,21 @@ begin
|
||||
AStream.WriteBuffer(rec, SizeOf(rec));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Write the left margin of the printed page (in inches)
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WriteLeftMargin(AStream: TStream);
|
||||
var
|
||||
dbl: double;
|
||||
begin
|
||||
{ BIFF record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_LEFTMARGIN, SizeOf(Double));
|
||||
|
||||
{ Page margin value, written in inches }
|
||||
dbl := mmToIn(FWorksheet.PageLayout.LeftMargin);
|
||||
AStream.WriteBuffer(dbl, SizeOf(dbl));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes a BIFF number format record defined in the specified format string
|
||||
(in Excel dialect).
|
||||
@ -2245,6 +2603,22 @@ begin
|
||||
SetLength(formula, 0);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes an Excel HCENTER record which determines whether the page is to be
|
||||
centered horizontally for printing
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WriteHCenter(AStream: TStream);
|
||||
var
|
||||
w: Word;
|
||||
begin
|
||||
{ BIFF record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_HCENTER, SizeOf(w));
|
||||
|
||||
{ Data }
|
||||
if poHorCentered in FWorksheet.PageLayout.Options then w := 1 else w := 0;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes a 64-bit floating point NUMBER record.
|
||||
Valid for BIFF5 and BIFF8 (BIFF2 has a different record structure).
|
||||
@ -2304,30 +2678,64 @@ end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes a PAGESETUP record containing information on printing
|
||||
Valid for BIFF5-8
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WritePageSetup(AStream: TStream);
|
||||
var
|
||||
dbl: Double;
|
||||
i: Integer;
|
||||
w: Word;
|
||||
begin
|
||||
{ BIFF record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_PAGESETUP, 9*2 + 2*8);
|
||||
|
||||
{ Paper size }
|
||||
AStream.WriteWord(WordToLE(0)); // 1 = Letter, 9 = A4
|
||||
w := 0;
|
||||
for i:=0 to High(PAPER_SIZES) do
|
||||
if (SameValue(PAPER_SIZES[i,0], FWorksheet.PageLayout.PageHeight) and
|
||||
SameValue(PAPER_SIZES[i,1], FWorksheet.PageLayout.PageWidth))
|
||||
or (SameValue(PAPER_SIZES[i,1], FWorksheet.PageLayout.PageHeight) and
|
||||
SameValue(PAPER_SIZES[i,0], FWorksheet.PageLayout.PageWidth))
|
||||
then begin
|
||||
w := i;
|
||||
break;
|
||||
end;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
|
||||
{ Scaling factor in percent }
|
||||
AStream.WriteWord(WordToLE(100)); // 100 %
|
||||
w := Round(FWorksheet.PageLayout.ScalingFactor);
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
|
||||
{ Start page number }
|
||||
AStream.WriteWord(WordToLE(1)); // starting at page 1
|
||||
w := FWorksheet.PageLayout.StartPageNumber;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
|
||||
{ Fit worksheet width to this number of pages, 0 = use as many as needed }
|
||||
AStream.WriteWord(WordToLE(0));
|
||||
w := FWorksheet.PageLayout.FitWidthToPages;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
|
||||
{ Fit worksheet height to this number of pages, 0 = use as many as needed }
|
||||
AStream.WriteWord(WordToLE(0));
|
||||
w := FWorksheet.PageLayout.FitHeightToPages;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
|
||||
AStream.WriteWord(WordToLE(0));
|
||||
{ Options:
|
||||
Bit 0: 0 = Print pages in columns; 1 = Print pages in rows
|
||||
Bit 1: 0 = Landscape; 1 = Portrait
|
||||
Bit 2: 1 = Paper size, scaling factor, paper orientation (portrait/landscape),
|
||||
print resolution and number of copies are not initialised
|
||||
Bit 3: 0 = Print coloured; 1 = Print black and white
|
||||
Bit 4: 0 = Default print quality; 1 = Draft quality
|
||||
Bit 5: 0 = Do not print cell notes; 1 = Print cell notes
|
||||
Bit 6: 0 = Use paper orientation (portrait/landscape) flag above
|
||||
1 = Use default paper orientation (landscape for chart sheets, portrait otherwise)
|
||||
Bit 7: 0 = Automatic page numbers; 1 = Use start page number above
|
||||
|
||||
The following flags are valid for BIFF8 only:
|
||||
Bit 9: 0 = Print notes as displayed; 1 = Print notes at end of sheet
|
||||
Bit 11-10: 00 = Print errors as displayed; 1 = Do not print errors
|
||||
2 = Print errors as “--”; 3 = Print errors as “#N/A” }
|
||||
w := GetPrintOptions;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
|
||||
{ Print resolution in dpi }
|
||||
AStream.WriteWord(WordToLE(600));
|
||||
@ -2336,13 +2744,16 @@ begin
|
||||
AStream.WriteWord(WordToLE(600));
|
||||
|
||||
{ Header margin }
|
||||
dbl := 0.5;
|
||||
dbl := mmToIn(FWorksheet.PageLayout.HeaderMargin);
|
||||
AStream.WriteBuffer(dbl, SizeOf(dbl));
|
||||
|
||||
{ Footer margin }
|
||||
dbl := mmToIn(FWorksheet.PageLayout.FooterMargin);
|
||||
AStream.WriteBuffer(dbl, SizeOf(dbl));
|
||||
|
||||
{ Number of copies to print }
|
||||
AStream.WriteWord(WordToLE(1)); // 1 copy
|
||||
w := FWorksheet.PageLayout.Copies;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -2418,6 +2829,36 @@ begin
|
||||
{ Not used (BIFF5-BIFF8 only, not written in BIFF2-BIFF4 }
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes out whether grid lines are printed or not
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WritePrintGridLines(AStream: TStream);
|
||||
var
|
||||
w: Word;
|
||||
begin
|
||||
{ Biff record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_PRINTGRID, SizeOf(w));
|
||||
|
||||
{ Data }
|
||||
if poPrintGridLines in FWorksheet.PageLayout.Options then w := 1 else w := 0;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes out whether column and row headers are printed or not
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WritePrintHeaders(AStream: TStream);
|
||||
var
|
||||
w: Word;
|
||||
begin
|
||||
{ Biff record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_PRINTHEADERS, SizeOf(w));
|
||||
|
||||
{ Data }
|
||||
if poPrintHeaders in FWorksheet.PageLayout.Options then w := 1 else w := 0;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes the address of a cell as used in an RPN formula and returns the
|
||||
count of bytes written.
|
||||
@ -2426,7 +2867,7 @@ end;
|
||||
function TsSpreadBIFFWriter.WriteRPNCellAddress(AStream: TStream;
|
||||
ARow, ACol: Cardinal; AFlags: TsRelFlags): Word;
|
||||
var
|
||||
r: Cardinal; // row index containing encoded relativ/absolute address info
|
||||
r: Cardinal; // row index containing encoded relative/absolute address info
|
||||
begin
|
||||
// Encoded row address
|
||||
r := ARow and MASK_EXCEL_ROW;
|
||||
@ -2813,6 +3254,22 @@ begin
|
||||
AStream.WriteWord(WordToLE(ASize));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes the right margin of the printed page (in inches)
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WriteRightMargin(AStream: TStream);
|
||||
var
|
||||
dbl: double;
|
||||
begin
|
||||
{ BIFF record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_RIGHTMARGIN, SizeOf(Double));
|
||||
|
||||
{ Page margin value, written in inches }
|
||||
dbl := mmToIn(FWorksheet.PageLayout.RightMargin);
|
||||
AStream.WriteBuffer(dbl, SizeOf(dbl));
|
||||
end;
|
||||
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes an Excel 3-8 ROW record
|
||||
Valid for BIFF3-BIFF8
|
||||
@ -3106,6 +3563,38 @@ begin
|
||||
Unused(AStream, AString);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Write the top margin of the printed page (in inches)
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WriteTopMargin(AStream: TStream);
|
||||
var
|
||||
dbl: double;
|
||||
begin
|
||||
{ BIFF record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_TOPMARGIN, SizeOf(Double));
|
||||
|
||||
{ Page margin value, written in inches }
|
||||
dbl := mmToIn(FWorksheet.PageLayout.TopMargin);
|
||||
AStream.WriteBuffer(dbl, SizeOf(dbl));
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes an Excel VCENTER record which determines whether the page is to be
|
||||
centered vertically for printing
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WriteVCenter(AStream: TStream);
|
||||
var
|
||||
w: Word;
|
||||
begin
|
||||
{ BIFF record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_VCENTER, SizeOf(w));
|
||||
|
||||
{ Data }
|
||||
if poVertCentered in FWorksheet.PageLayout.Options then w := 1 else w := 0;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
end;
|
||||
|
||||
|
||||
procedure TsSpreadBIFFWriter.WriteVirtualCells(AStream: TStream);
|
||||
var
|
||||
r,c: Cardinal;
|
||||
|
@ -79,6 +79,7 @@ type
|
||||
procedure ReadNumFormats(ANode: TDOMNode);
|
||||
procedure ReadPageMargins(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
||||
procedure ReadPalette(ANode: TDOMNode);
|
||||
procedure ReadPrintOptions(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
||||
procedure ReadRowHeight(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
||||
procedure ReadSharedStrings(ANode: TDOMNode);
|
||||
procedure ReadSheetFormatPr(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
||||
@ -131,7 +132,10 @@ type
|
||||
procedure WriteNumFormatList(AStream: TStream);
|
||||
procedure WritePalette(AStream: TStream);
|
||||
procedure WritePageMargins(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
procedure WritePageSetup(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
procedure WritePrintOptions(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
procedure WriteSheetData(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
procedure WriteSheetPr(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
procedure WriteSheetViews(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
procedure WriteStyleList(AStream: TStream; ANodeName: String);
|
||||
procedure WriteVmlDrawings(AWorksheet: TsWorksheet);
|
||||
@ -1307,38 +1311,33 @@ procedure TsSpreadOOXMLReader.ReadPageMargins(ANode: TDOMNode;
|
||||
AWorksheet: TsWorksheet);
|
||||
var
|
||||
s: String;
|
||||
layout: TsPageLayout;
|
||||
begin
|
||||
if ANode = nil then
|
||||
if (ANode = nil) or (AWorksheet = nil) then // just to make sure...
|
||||
exit;
|
||||
|
||||
layout := AWorksheet.PageLayout;
|
||||
|
||||
s := GetAttrValue(ANode, 'left');
|
||||
if s <> '' then
|
||||
layout.LeftMargin := HtmlLengthStrToPts(s);
|
||||
AWorksheet.PageLayout.LeftMargin := PtsToMM(HtmlLengthStrToPts(s, 'in'));
|
||||
|
||||
s := GetAttrValue(ANode, 'right');
|
||||
if s <> '' then
|
||||
layout.RightMargin := HtmlLengthStrToPts(s);
|
||||
AWorksheet.PageLayout.RightMargin := PtsToMM(HtmlLengthStrToPts(s, 'in'));
|
||||
|
||||
s := GetAttrValue(ANode, 'top');
|
||||
if s <> '' then
|
||||
layout.TopMargin := HtmlLengthStrToPts(s);
|
||||
AWorksheet.PageLayout.TopMargin := PtsToMM(HtmlLengthStrToPts(s, 'in'));
|
||||
|
||||
s := GetAttrValue(ANode, 'bottom');
|
||||
if s <> '' then
|
||||
layout.BottomMargin := HtmlLengthStrToPts(s);
|
||||
AWorksheet.PageLayout.BottomMargin := PtsToMM(HtmlLengthStrToPts(s, 'in'));
|
||||
|
||||
s := GetAttrValue(ANode, 'header');
|
||||
if s <> '' then
|
||||
layout.HeaderDistance := HtmlLengthStrToPts(s);
|
||||
AWorksheet.PageLayout.HeaderMargin := PtsToMM(HtmlLengthStrToPts(s, 'in'));
|
||||
|
||||
s := GetAttrValue(ANode, 'footer');
|
||||
if s <> '' then
|
||||
layout.FooterDistance := HtmlLengthStrToPts(s);
|
||||
|
||||
AWorksheet.PageLayout := layout;
|
||||
AWorksheet.PageLayout.FooterMargin := PtsToMM(HtmlLengthStrToPts(s, 'in'));
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadPalette(ANode: TDOMNode);
|
||||
@ -1385,6 +1384,22 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadPrintOptions(ANode: TDOMNode;
|
||||
AWorksheet: TsWorksheet);
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
if ANode = nil then
|
||||
exit;
|
||||
s := GetAttrValue(ANode, 'headings');
|
||||
if (s = '1') then
|
||||
Include(AWorksheet.PageLayout.Options, poPrintHeaders);
|
||||
|
||||
s := GetAttrValue(ANode, 'gridLines');
|
||||
if (s = '1') then
|
||||
Include(AWorksheet.PageLayout.Options, poPrintGridLines);
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadRowHeight(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
||||
var
|
||||
s: String;
|
||||
@ -1709,6 +1724,7 @@ begin
|
||||
ReadWorksheet(Doc.DocumentElement.FindNode('sheetData'), FWorksheet);
|
||||
ReadMergedCells(Doc.DocumentElement.FindNode('mergeCells'), FWorksheet);
|
||||
ReadHyperlinks(Doc.DocumentElement.FindNode('hyperlinks'));
|
||||
ReadPrintOptions(Doc.DocumentElement.FindNode('printOptions'), FWorksheet);
|
||||
ReadPageMargins(Doc.DocumentElement.FindNode('pageMargins'), FWorksheet);
|
||||
|
||||
FreeAndNil(Doc);
|
||||
@ -2309,12 +2325,87 @@ begin
|
||||
with AWorksheet.PageLayout do
|
||||
AppendToStream(AStream, Format(
|
||||
'<pageMargins left="%g" right="%g" top="%g" bottom="%g" header="%g" footer="%g" />', [
|
||||
PtsToIn(LeftMargin), PtsToIn(RightMargin), PtsToIn(TopMargin), PtsToIn(BottomMargin),
|
||||
PtsToIn(HeaderDistance), PtsToIn(FooterDistance) ],
|
||||
mmToIn(LeftMargin), mmToIn(RightMargin), mmToIn(TopMargin), mmToIn(BottomMargin),
|
||||
mmToIn(HeaderMargin), mmToIn(FooterMargin) ],
|
||||
FPointSeparatorSettings
|
||||
));
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLWriter.WritePageSetup(AStream: TStream;
|
||||
AWorksheet: TsWorksheet);
|
||||
var
|
||||
s: String;
|
||||
i: Integer;
|
||||
begin
|
||||
s := '';
|
||||
|
||||
// Paper size
|
||||
for i:=0 to High(PAPER_SIZES) do
|
||||
if (SameValue(PAPER_SIZES[i,0], AWorksheet.PageLayout.PageHeight) and
|
||||
SameValue(PAPER_SIZES[i,1], AWorksheet.PageLayout.PageWidth))
|
||||
or (SameValue(PAPER_SIZES[i,1], AWorksheet.PageLayout.PageHeight) and
|
||||
SameValue(PAPER_SIZES[i,0], AWorksheet.PageLayout.PageWidth))
|
||||
then begin
|
||||
s := Format('%s paperSize="%d"', [s, i]);
|
||||
break;
|
||||
end;
|
||||
|
||||
// Scaling factor
|
||||
if AWorksheet.PageLayout.ScalingFactor <> 100 then
|
||||
s := Format('%s scale="%.0f" fitToHeight="0" fitToWidth="0"', [
|
||||
s, AWorksheet.PageLayout.ScalingFactor
|
||||
], FPointSeparatorSettings);
|
||||
|
||||
// Fit width pages
|
||||
if AWorksheet.PageLayout.FitWidthToPages > 0 then
|
||||
s := Format('%s fitToWidth="%d"', [s, AWorksheet.PageLayout.FitWidthToPages]);
|
||||
|
||||
// Fit height pages
|
||||
if AWorksheet.PageLayout.FitHeightToPages > 0 then
|
||||
s := Format('%s fitToHeight="%d"', [s, AWorksheet.PageLayout.FitHeightToPages]);
|
||||
|
||||
// Orientation
|
||||
s := Format('%s orientation="%s"', [
|
||||
s, IfThen(AWorksheet.PageLayout.Orientation = spoPortrait, 'portrait', 'landscape')
|
||||
]);
|
||||
|
||||
// First page number
|
||||
if poUseStartPageNumber in FWorksheet.PageLayout.Options then
|
||||
s := Format('%s useFirstPageNumber="%d"', [s, AWorksheet.PageLayout.StartPageNumber]);
|
||||
|
||||
// Print order
|
||||
if poPrintPagesByRows in AWorksheet.PageLayout.Options then
|
||||
s := s + ' pageOrder="overThenDown"';
|
||||
|
||||
// Monochrome
|
||||
if poMonochrome in AWorksheet.PageLayout.Options then
|
||||
s := s + ' blackAndWhite="1"';
|
||||
|
||||
// Quality
|
||||
if poDraftQuality in AWOrksheet.PageLayout.Options then
|
||||
s := s + ' draft="1"';
|
||||
|
||||
if s <> '' then
|
||||
AppendToStream(AStream,
|
||||
'<pageSetup' + s + ' />');
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLWriter.WritePrintOptions(AStream: TStream;
|
||||
AWorksheet: TsWorksheet);
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
s := '';
|
||||
if poPrintGridLines in AWorksheet.PageLayout.Options then
|
||||
s := s + ' gridLines="1"';
|
||||
if poPrintHeaders in AWorksheet.PageLayout.Options then
|
||||
s := s + ' headings="1"';
|
||||
|
||||
if s <> '' then
|
||||
AppendToStream(AStream,
|
||||
'<printOptions' + s + ' />');
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLWriter.WriteSheetData(AStream: TStream;
|
||||
AWorksheet: TsWorksheet);
|
||||
var
|
||||
@ -2424,6 +2515,21 @@ begin
|
||||
'</sheetData>');
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLWriter.WriteSheetPr(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
s := '';
|
||||
if (AWorksheet.PageLayout.FitWidthToPages > 0) or
|
||||
(AWorksheet.PageLayout.FitHeightToPages > 0) then
|
||||
s := s + ' fitToPage="1"';
|
||||
if s <> '' then s := '<pageSetUpPr' + s + ' />';
|
||||
|
||||
if s <> '' then
|
||||
AppendToStream(AStream,
|
||||
'<sheetPr>' + s + '</sheetPr>');
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLWriter.WriteSheetViews(AStream: TStream;
|
||||
AWorksheet: TsWorksheet);
|
||||
var
|
||||
@ -2936,13 +3042,16 @@ begin
|
||||
AppendToStream(FSSheets[FCurSheetNum], Format(
|
||||
'<worksheet xmlns="%s" xmlns:r="%s">', [SCHEMAS_SPREADML, SCHEMAS_DOC_RELS]));
|
||||
|
||||
WriteSheetPr(FSSheets[FCurSheetNum], AWorksheet);
|
||||
WriteDimension(FSSheets[FCurSheetNum], AWorksheet);
|
||||
WriteSheetViews(FSSheets[FCurSheetNum], AWorksheet);
|
||||
WriteCols(FSSheets[FCurSheetNum], AWorksheet);
|
||||
WriteSheetData(FSSheets[FCurSheetNum], AWorksheet);
|
||||
WriteHyperlinks(FSSheets[FCurSheetNum], AWorksheet);
|
||||
WriteMergedCells(FSSheets[FCurSheetNum], AWorksheet);
|
||||
WritePrintOptions(FSSheets[FCurSheetNum], AWorksheet);
|
||||
WritePageMargins(FSSheets[FCurSheetNum], AWorksheet);
|
||||
WritePageSetup(FSSheets[FCurSheetNum], AWorksheet);
|
||||
|
||||
// Footer
|
||||
if AWorksheet.Comments.Count > 0 then
|
||||
|
Reference in New Issue
Block a user