Table of Contents

BiffWriter Struct

Definition

Namespace
Bodu.IO.Biff
Assembly
Bodu.IO.Biff.dll
Package
Bodu.IO.Biff 1.0.0
Source
BiffWriter.Cells.cs

Provides a forward-only writer that emits BIFF5 or BIFF8 records to an IBufferWriter<T>. Raw records are written from an identifier and payload; the records the codec names are written from typed values in the layout the selected version requires.

public ref struct BiffWriter
Inherited Members

Remarks

The writer is created with an explicit BiffVersion and never mixes versions: a record that exists only in BIFF8 (the shared string table, LABELSST) is rejected under BIFF5, and text is encoded as Unicode under BIFF8 and in the configured code page under BIFF5. Every record is checked against the version's maximum payload length; WriteContinuedRecord(ushort, scoped ReadOnlySpan<byte>) and WriteSst(scoped ReadOnlySpan<string>) split oversized structures into CONTINUE records according to the format's rules.

The writer serializes records, not workbooks: it does not order records, compute the sheet offsets a BOUNDSHEET record carries, or maintain a cell model. BytesCommitted reports the stream position so a caller assembling a workbook can compute those offsets. The only sequence rule enforced is that an EOF closes a substream a BOF opened.

The writer is a ref struct whose mutable counters live in a shared heap object, so a copy taken by value continues the same stream.

var output = new ArrayBufferWriter<byte>();
var writer = new BiffWriter(output, BiffVersion.Biff8);

writer.WriteBof(BiffSubstreamType.Worksheet);
writer.WriteNumber(row: 0, column: 0, xfIndex: 15, value: 42.5);
writer.WriteLabel(row: 0, column: 1, xfIndex: 15, "inline text");
writer.WriteEof();

// output.WrittenSpan now holds a minimal worksheet substream.

Constructors

BiffWriter(IBufferWriter<byte>, BiffVersion)

Initializes a new instance of the BiffWriter struct emitting the specified version.

public BiffWriter(IBufferWriter<byte> output, BiffVersion version)

Parameters

output IBufferWriter<byte>

The destination buffer writer.

version BiffVersion

The BIFF version to emit.

Exceptions

ArgumentNullException

Thrown when output is null.

ArgumentOutOfRangeException

Thrown when version is not Biff5 or Biff8.

BiffWriter(IBufferWriter<byte>, BiffWriterOptions)

Initializes a new instance of the BiffWriter struct using the supplied options.

public BiffWriter(IBufferWriter<byte> output, BiffWriterOptions options)

Parameters

output IBufferWriter<byte>

The destination buffer writer.

options BiffWriterOptions

The options selecting the version and the BIFF5 code page.

Exceptions

ArgumentNullException

Thrown when output is null.

ArgumentOutOfRangeException

Thrown when the options select a version other than Biff5 or Biff8.

Properties

BytesCommitted

Gets the number of bytes written so far: the stream offset at which the next record's header will begin.

public readonly long BytesCommitted { get; }

Property Value

long

The byte count, useful for computing the substream offsets a BOUNDSHEET record carries.

CodePage

Gets the code page used to encode text under BIFF5.

public readonly int CodePage { get; }

Property Value

int

The Windows code page number.

MaxPayloadLength

Gets the largest payload a single record may carry under the version being emitted.

public readonly int MaxPayloadLength { get; }

Property Value

int

The maximum payload length in bytes.

OpenSubstreamDepth

Gets the number of substreams opened by a BOF and not yet closed by an EOF.

public readonly int OpenSubstreamDepth { get; }

Property Value

int

The open substream depth; zero when the stream is balanced.

Version

Gets the BIFF version being emitted.

public readonly BiffVersion Version { get; }

Property Value

BiffVersion

The version.

Methods

WriteBlank(int, int, ushort)

Writes a BLANK record: a formatted cell carrying no value.

public void WriteBlank(int row, int column, ushort xfIndex)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

Exceptions

ArgumentOutOfRangeException

Thrown when row or column is outside the 16-bit range.

WriteBof(BiffSubstreamType, ushort, ushort)

Writes a BOF record opening a substream of the specified kind, in the layout of the version being emitted.

public void WriteBof(BiffSubstreamType substreamType, ushort build = 0, ushort year = 0)

Parameters

substreamType BiffSubstreamType

The kind of substream.

build ushort

The build identifier to record.

year ushort

The build year to record.

WriteBoolErr(int, int, ushort, byte, bool)

Writes a BOOLERR record from its raw value byte and kind flag.

public void WriteBoolErr(int row, int column, ushort xfIndex, byte rawValue, bool isError)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

rawValue byte

The value byte.

isError bool

Whether the value byte is an error code.

Exceptions

ArgumentOutOfRangeException

Thrown when row or column is outside the 16-bit range.

WriteBoolean(int, int, ushort, bool)

Writes a BOOLERR record holding a boolean.

public void WriteBoolean(int row, int column, ushort xfIndex, bool value)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

value bool

The boolean value.

Exceptions

ArgumentOutOfRangeException

Thrown when row or column is outside the 16-bit range.

WriteBoundSheet(uint, BiffSheetState, BiffSheetType, scoped ReadOnlySpan<char>)

Writes a BOUNDSHEET record: one entry of the sheet directory.

public void WriteBoundSheet(uint streamOffset, BiffSheetState state, BiffSheetType sheetType, scoped ReadOnlySpan<char> name)

Parameters

streamOffset uint

The absolute offset of the sheet's BOF record within the workbook stream.

state BiffSheetState

The sheet's visibility.

sheetType BiffSheetType

The kind of sheet.

name ReadOnlySpan<char>

The sheet name.

Exceptions

ArgumentOutOfRangeException

Thrown when the encoded name is longer than 255 bytes or characters.

WriteCodePage(ushort)

Writes a CODEPAGE record.

public void WriteCodePage(ushort codePage)

Parameters

codePage ushort

The code page value to record, as the format stores it.

WriteContinuedRecord(ushort, scoped ReadOnlySpan<byte>)

Writes a record whose payload may exceed the maximum record length, splitting the overflow into CONTINUE records at the maximum length.

public void WriteContinuedRecord(ushort recordId, scoped ReadOnlySpan<byte> payload)

Parameters

recordId ushort

The 16-bit record identifier.

payload ReadOnlySpan<byte>

The logical payload.

Remarks

The split is byte-oriented: it is correct for structures the format allows to continue at any byte (drawing and text objects, for example) but not for the shared string table, whose continuation must restart at a character boundary with a fresh flags byte - use WriteSst(scoped ReadOnlySpan<string>) for that.

WriteDateMode(bool)

Writes a DATEMODE record.

public void WriteDateMode(bool is1904)

Parameters

is1904 bool

Whether the workbook uses the 1904 date system.

WriteDimensions(in BiffDimensionsRecord)

Writes a DIMENSIONS record in the layout of the version being emitted.

public void WriteDimensions(in BiffDimensionsRecord record)

Parameters

record BiffDimensionsRecord

The used range.

Exceptions

ArgumentOutOfRangeException

Thrown when a field is negative, a column exceeds the 16-bit range, or under BIFF5 a row exceeds the 16-bit range.

WriteEof()

Writes an EOF record closing the innermost open substream.

public void WriteEof()

Exceptions

InvalidOperationException

Thrown when no substream is open.

WriteError(int, int, ushort, byte)

Writes a BOOLERR record holding an error code.

public void WriteError(int row, int column, ushort xfIndex, byte errorCode)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

errorCode byte

The BIFF error code.

Exceptions

ArgumentOutOfRangeException

Thrown when row or column is outside the 16-bit range.

WriteFont(ushort, ushort, ushort, ushort, ushort, byte, byte, byte, scoped ReadOnlySpan<char>)

Writes a FONT record.

public void WriteFont(ushort height, ushort attributes, ushort colorIndex, ushort weight, ushort escapement, byte underline, byte family, byte characterSet, scoped ReadOnlySpan<char> name)

Parameters

height ushort

The font height in twips.

attributes ushort

The attribute flags: italic (bit 1), strikeout (bit 3), outline (bit 4), shadow (bit 5).

colorIndex ushort

The palette color index; 0x7FFF for automatic.

weight ushort

The weight: 400 normal, 700 bold.

escapement ushort

The escapement: 0 none, 1 superscript, 2 subscript.

underline byte

The underline type.

family byte

The font family.

characterSet byte

The character set.

name ReadOnlySpan<char>

The face name.

Exceptions

ArgumentOutOfRangeException

Thrown when the encoded name is longer than 255 bytes or characters.

WriteFormat(ushort, scoped ReadOnlySpan<char>)

Writes a FORMAT record: a number-format index and its code.

public void WriteFormat(ushort formatIndex, scoped ReadOnlySpan<char> code)

Parameters

formatIndex ushort

The number-format index.

code ReadOnlySpan<char>

The format code.

Exceptions

ArgumentOutOfRangeException

Thrown when the encoded code does not fit the record.

WriteFormula(int, int, ushort, BiffCachedResultKind, byte, scoped ReadOnlySpan<byte>, ushort)

Writes a FORMULA record whose cached result is a string, boolean, error, or empty marker.

public void WriteFormula(int row, int column, ushort xfIndex, BiffCachedResultKind cachedResultKind, byte cachedValue, scoped ReadOnlySpan<byte> tokens, ushort flags = 0)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

cachedResultKind BiffCachedResultKind

The kind of cached result; a string result is carried by a following STRING record.

cachedValue byte

The boolean (zero or one) or error code byte; ignored for other kinds.

tokens ReadOnlySpan<byte>

The parsed-expression tokens (rgce), written verbatim.

flags ushort

The option flags (grbit).

Exceptions

ArgumentOutOfRangeException

Thrown when cachedResultKind is Number or undefined, row or column is outside the 16-bit range, or the tokens do not fit the record.

WriteFormula(int, int, ushort, double, scoped ReadOnlySpan<byte>, ushort)

Writes a FORMULA record whose cached result is a number.

public void WriteFormula(int row, int column, ushort xfIndex, double cachedValue, scoped ReadOnlySpan<byte> tokens, ushort flags = 0)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

cachedValue double

The cached numeric result.

tokens ReadOnlySpan<byte>

The parsed-expression tokens (rgce), written verbatim.

flags ushort

The option flags (grbit).

Exceptions

ArgumentOutOfRangeException

Thrown when row or column is outside the 16-bit range, or the tokens do not fit the record.

WriteLabel(int, int, ushort, scoped ReadOnlySpan<char>)

Writes a LABEL record: an inline text cell.

public void WriteLabel(int row, int column, ushort xfIndex, scoped ReadOnlySpan<char> text)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

text ReadOnlySpan<char>

The cell text.

Exceptions

ArgumentOutOfRangeException

Thrown when row or column is outside the 16-bit range, or the encoded text does not fit the record.

WriteLabelSst(int, int, ushort, uint)

Writes a LABELSST record: a text cell referencing the shared string table (BIFF8 only).

public void WriteLabelSst(int row, int column, ushort xfIndex, uint sstIndex)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

sstIndex uint

The zero-based index of the text in the shared string table.

Exceptions

InvalidOperationException

Thrown when the writer emits BIFF5.

ArgumentOutOfRangeException

Thrown when row or column is outside the 16-bit range.

WriteMulBlank(int, int, scoped ReadOnlySpan<ushort>)

Writes a MULBLANK record: a run of adjacent blank cells in one row.

public void WriteMulBlank(int row, int firstColumn, scoped ReadOnlySpan<ushort> xfIndices)

Parameters

row int

The zero-based row index.

firstColumn int

The zero-based column index of the first cell.

xfIndices ReadOnlySpan<ushort>

The extended-format index of each cell, in column order.

Exceptions

ArgumentOutOfRangeException

Thrown when the row or a column index is outside the 16-bit range, or the run does not fit the record.

ArgumentException

Thrown when xfIndices is empty.

WriteMulRk(int, int, scoped ReadOnlySpan<BiffRkCell>)

Writes a MULRK record: a run of adjacent RK-encoded cells in one row.

public void WriteMulRk(int row, int firstColumn, scoped ReadOnlySpan<BiffRkCell> cells)

Parameters

row int

The zero-based row index.

firstColumn int

The zero-based column index of the first cell.

cells ReadOnlySpan<BiffRkCell>

The cells, in column order.

Exceptions

ArgumentOutOfRangeException

Thrown when the row or a column index is outside the 16-bit range, or the run does not fit the record.

ArgumentException

Thrown when cells is empty.

WriteNumber(int, int, ushort, double)

Writes a NUMBER record: a cell holding a double-precision value.

public void WriteNumber(int row, int column, ushort xfIndex, double value)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

value double

The cell value.

Exceptions

ArgumentOutOfRangeException

Thrown when row or column is outside the 16-bit range.

WriteRecord(BiffRecordType, scoped ReadOnlySpan<byte>)

Writes a record of a named type from its payload.

public void WriteRecord(BiffRecordType recordType, scoped ReadOnlySpan<byte> payload)

Parameters

recordType BiffRecordType

The record type.

payload ReadOnlySpan<byte>

The record payload.

Exceptions

ArgumentOutOfRangeException

Thrown when payload is longer than MaxPayloadLength.

WriteRecord(ushort, scoped ReadOnlySpan<byte>)

Writes a record from its identifier and payload.

public void WriteRecord(ushort recordId, scoped ReadOnlySpan<byte> payload)

Parameters

recordId ushort

The 16-bit record identifier.

payload ReadOnlySpan<byte>

The record payload.

Exceptions

ArgumentOutOfRangeException

Thrown when payload is longer than MaxPayloadLength.

WriteRk(int, int, ushort, uint)

Writes an RK record: a cell holding an RK-encoded number.

public void WriteRk(int row, int column, ushort xfIndex, uint rk)

Parameters

row int

The zero-based row index.

column int

The zero-based column index.

xfIndex ushort

The extended-format index of the cell.

rk uint

The RK value, as produced by TryEncode(double, out uint).

Exceptions

ArgumentOutOfRangeException

Thrown when row or column is outside the 16-bit range.

WriteRow(in BiffRowRecord)

Writes a ROW record.

public void WriteRow(in BiffRowRecord record)

Parameters

record BiffRowRecord

The row description.

Exceptions

ArgumentOutOfRangeException

Thrown when the row or column fields are outside the 16-bit range.

WriteSst(scoped ReadOnlySpan<string>)

Writes a shared string table (SST) from the supplied unique strings, splitting it into CONTINUE records as the format requires (BIFF8 only).

public void WriteSst(scoped ReadOnlySpan<string> strings)

Parameters

strings ReadOnlySpan<string>

The unique strings, in the order cells reference them.

Remarks

The total reference count is recorded as the number of strings; use WriteSst(scoped ReadOnlySpan<string>, uint) to record the actual number of LABELSST cells.

Exceptions

InvalidOperationException

Thrown when the writer emits BIFF5.

ArgumentOutOfRangeException

Thrown when a string is longer than 65,535 characters.

WriteSst(scoped ReadOnlySpan<string>, uint)

Writes a shared string table (SST) from the supplied unique strings and reference count, splitting it into CONTINUE records as the format requires (BIFF8 only).

public void WriteSst(scoped ReadOnlySpan<string> strings, uint totalReferenceCount)

Parameters

strings ReadOnlySpan<string>

The unique strings, in the order cells reference them.

totalReferenceCount uint

The number of LABELSST cells that reference the table.

Remarks

A string's header is never split across records; its characters may be, at a character boundary, and each continued run restarts with its own flags byte - the rules BiffSstReader decodes by.

Exceptions

InvalidOperationException

Thrown when the writer emits BIFF5.

ArgumentOutOfRangeException

Thrown when a string is longer than 65,535 characters.

WriteString(scoped ReadOnlySpan<char>)

Writes a STRING record: the cached text result of the preceding formula.

public void WriteString(scoped ReadOnlySpan<char> text)

Parameters

text ReadOnlySpan<char>

The cached text.

Exceptions

ArgumentOutOfRangeException

Thrown when the encoded text does not fit the record.

WriteXf(in BiffXfRecord)

Writes an XF record carrying the font, format, and type fields; the alignment, border, and fill fields that follow are written as zeros.

public void WriteXf(in BiffXfRecord record)

Parameters

record BiffXfRecord

The extended format.

Applies to

ProductVersions
.NET8, 10