import "@sheetwrite/xlsx/register" ;
declare const bytes : Uint8Array ;
The recorded LibreOffice 26.8 comparison in PR #190 reports:
Chain Unexpected differences Known producer difference Sheetwrite → LibreOffice → Sheetwrite 0 LibreOffice omits conditional-rule stopIfTrue. LibreOffice → Sheetwrite → LibreOffice → Sheetwrite 0 Known producer differences remain separately recorded.
A passing semantic comparison does not mean byte-identical files or full Excel feature support.
Try it live: producer compatibility evidence .
Full setup
Use the public importer on bytes from a host-selected LibreOffice file. No special LibreOffice backend is required:
import "@sheetwrite/xlsx/register" ;
const input = document . querySelector < HTMLInputElement >( 'input[type="file"]' ); const file = input ?. files ?.[ 0 ];
if ( ! file ) throw new Error ( "Choose a LibreOffice-saved XLSX file first" );
console . log ( output . byteLength );
This converts the selected file. It does not invoke LibreOffice or run the repository's producer comparison.
Display and layout fidelity
Field Import/export behavior Vertical alignment Native absent/bottom imports as bottom, matching Excel. Native center maps to the grid's middle default. Export writes the default as center and an explicit middle override where a bottom column default would otherwise apply. Column width Uses OOXML's maximum-digit-width conversion rather than adding 2–3 px on each cycle. Sheetwrite pixel widths round-trip exactly; native fixture widths no longer include the old extra 5 px. Row height ht without customHeight="1" remains automatic, not fixed.Hyperlink display An absent display uses the cell text. An explicitly empty display remains empty. Hyperlink appearance Export retains the link's font. Default link color/underline applies only to properties the cell style does not set. Explicit cell styling wins when painting.
What the comparison proves
The evidence compares normalized workbook semantics, not ZIP/XML identity. Generated hyperlink IDs may change. Hyperlink presentation moved into cell styles compares equal only when the painted appearance remains equal.
PR #189 separates workbook.xlsxSource opaque bytes from semantic comparison. LibreOffice can rename parts and add its own theme or document-property graphs. Retained graphs are checked separately by count per kind : owner, sheet and relationship type. The result must retain at least as many graphs of each kind as the source; additions are allowed.
That detects a lost chart, pivot or drawing count. It cannot detect one graph dropped and replaced by another of the same kind on the same owner. It does not prove opaque payload identity across different producers. A direct Sheetwrite no-edit round trip retains eligible original compressed payloads .
Known producer difference
LibreOffice does not write stopIfTrue. The comparison records its omission in knownProducerDifferences, separate from unexpected differences; it does not pretend the conditional-format behavior survived unchanged. If later matching rules matter, inspect the file and warnings after resaving in LibreOffice.
The reported pass is for the pinned fixtures and LibreOffice 26.8 in PR #190. It is not a claim that every workbook, feature or producer version round-trips without loss. The earlier #189 result still had 19 differences; #190 resolves the display/layout differences and records the known stop-rule loss.
See also
function fromXlsxWorkbook(data: ArrayBuffer | Uint8Array, options?: XlsxWorkbookOptions): Promise<WorkbookSnapshot> function fromXlsxWorkbook (
data : ArrayBuffer | Uint8Array ,
options ?: XlsxWorkbookOptions ,
) : Promise < WorkbookSnapshot > function fromXlsxWorkbook (
data : ArrayBuffer | Uint8Array ,
options ?: XlsxWorkbookOptions ,
) : Promise < WorkbookSnapshot > Formula-preserving, multi-sheet workbook import through the optional XLSX backend. Example import { registerXlsxBackends } from "@sheetwrite/xlsx" ;
import { fromXlsxWorkbook, createGridFromSnapshot, initSheetwrite } from "@sheetwrite/core" ;
registerXlsxBackends ();
async function openWorkbook ( host : HTMLElement , file : File ) {
await initSheetwrite ();
const snapshot = await fromXlsxWorkbook ( await file. arrayBuffer ());
return createGridFromSnapshot (host, snapshot);
} See also toXlsxWorkbook API reference → function toXlsxWorkbook(input: WorkbookSnapshot | Pick<Grid, "exportSnapshot">, options?: XlsxWorkbookOptions): Promise<Uint8Array> function toXlsxWorkbook (
input : WorkbookSnapshot | Pick < Grid , "exportSnapshot" >,
options ?: XlsxWorkbookOptions ,
) : Promise < Uint8Array > function toXlsxWorkbook (
input :
| WorkbookSnapshot
| Pick <
Grid ,
"exportSnapshot"
>,
options ?: XlsxWorkbookOptions ,
) : Promise < Uint8Array > Formula-preserving, multi-sheet workbook export through the optional XLSX backend. Example import { registerXlsxBackends } from "@sheetwrite/xlsx" ;
import { toXlsxWorkbook, downloadBytes, type Grid } from "@sheetwrite/core" ;
registerXlsxBackends ();
async function download ( grid : Grid ) {
const bytes = await toXlsxWorkbook (grid);
downloadBytes (bytes, "workbook.xlsx" , "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
} See also fromXlsxWorkbook API reference → const bytes: Uint8Array<ArrayBufferLike> const bytes : Uint8Array < ArrayBufferLike > const bytes : Uint8Array < ArrayBufferLike > interface Uint8Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike> interface Uint8Array < TArrayBuffer extends ArrayBufferLike = ArrayBufferLike > interface Uint8Array < TArrayBuffer extends ArrayBufferLike = ArrayBufferLike > A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised. const snapshot: WorkbookSnapshot const snapshot : WorkbookSnapshot const snapshot : WorkbookSnapshot API reference → XlsxWorkbookOptions.onWarning?: ((warning: XlsxWorkbookWarning) => void) | undefined interface XlsxWorkbookOptions {
onWarning ?: (( warning : XlsxWorkbookWarning ) => void ) | undefined ;
} interface XlsxWorkbookOptions {
onWarning ?:
| ((
warning : XlsxWorkbookWarning ,
) => void )
| undefined ;
} warning: XlsxWorkbookWarning let warning : XlsxWorkbookWarning let warning : XlsxWorkbookWarning API reference → var console: Console var console : Console var console : Console Console.warn(...data: any[]): void (+1 overload) Console. warn ( ... data: any[]): void ( + 1 overload) Console. warn ( ... data: any[]): void ( + 1 overload) The console.warn() static method outputs a warning message to the console at the 'warning' log level. MDN Reference XlsxWorkbookWarning.code: "boolean-literal" | "rich-text" | "hyperlink" | "unsupported-cell-value" | "unsupported-feature" | "external-relationship" | "external-formula" | "format-loss" | "validation-loss" | "invalid-metadata" interface XlsxWorkbookWarning {
code :
| "boolean-literal"
| "rich-text"
| "hyperlink"
| "unsupported-cell-value"
| "unsupported-feature"
| "external-relationship"
| "external-formula"
| "format-loss"
| "validation-loss"
| "invalid-metadata" ;
} interface XlsxWorkbookWarning {
code :
| "boolean-literal"
| "rich-text"
| "hyperlink"
| "unsupported-cell-value"
| "unsupported-feature"
| "external-relationship"
| "external-formula"
| "format-loss"
| "validation-loss"
| "invalid-metadata" ;
} API reference → XlsxWorkbookWarning.message: string interface XlsxWorkbookWarning {
message : string ;
} interface XlsxWorkbookWarning {
message : string ;
} API reference → const output: Uint8Array<ArrayBufferLike> const output : Uint8Array < ArrayBufferLike > const output : Uint8Array < ArrayBufferLike > function fromXlsxWorkbookFile(file: Blob, options?: XlsxWorkbookOptions): Promise<WorkbookSnapshot> function fromXlsxWorkbookFile (
file : Blob ,
options ?: XlsxWorkbookOptions ,
) : Promise < WorkbookSnapshot > function fromXlsxWorkbookFile (
file : Blob ,
options ?: XlsxWorkbookOptions ,
) : Promise < WorkbookSnapshot > Import a seekable File/Blob without first buffering the compressed workbook. API reference → const input: HTMLInputElement | null const input : HTMLInputElement | null const input : HTMLInputElement | null var document: Document var document : Document var document : Document window.document returns a reference to the document contained in the window. MDN Reference API reference → ParentNode.querySelector<HTMLInputElement>(selectors: string): HTMLInputElement | null (+4 overloads) ParentNode. querySelector < HTMLInputElement >(selectors: string): HTMLInputElement | null ( + 4 overloads) ParentNode. querySelector < HTMLInputElement >(selectors: string): HTMLInputElement | null ( + 4 overloads) Returns the first element that is a descendant of node that matches selectors. MDN Reference interface HTMLInputElement interface HTMLInputElement interface HTMLInputElement The HTMLInputElement interface provides special properties and methods for manipulating the options, layout, and presentation of input elements. MDN Reference const file: File | undefined const file : File | undefined const file :
File | undefined HTMLInputElement.files: FileList | null | undefined interface HTMLInputElement {
files : FileList | null | undefined ;
} interface HTMLInputElement {
files :
FileList | null | undefined ;
} The HTMLInputElement.files property allows you to access the FileList selected with the <input type='file'> element. MDN Reference var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+2 overloads) var Error : ErrorConstructor
new ( message ?: string , options ?: ErrorOptions ) => Error ( + 2 overloads) var Error : ErrorConstructor
new ( message ?: string , options ?: ErrorOptions ) => Error ( + 2 overloads) const options: {
onWarning: (warning: import("@sheetwrite/core").XlsxWorkbookWarning) => void;
} const options : {
onWarning : (
warning : import ( "@sheetwrite/core" ). XlsxWorkbookWarning ,
) => void ;
} const options : {
onWarning : (
warning : import ( "@sheetwrite/core" ). XlsxWorkbookWarning ,
) => void ;
} API reference → onWarning: (warning: import("@sheetwrite/core").XlsxWorkbookWarning) => void let onWarning : (
warning : import ( "@sheetwrite/core" ). XlsxWorkbookWarning ,
) => void let onWarning : (
warning : import ( "@sheetwrite/core" ). XlsxWorkbookWarning ,
) => void API reference → interface XlsxWorkbookWarning
export XlsxWorkbookWarning interface XlsxWorkbookWarning
export XlsxWorkbookWarning interface XlsxWorkbookWarning
export XlsxWorkbookWarning Structured fidelity warning emitted during XLSX conversion. API reference → const file: File const file : File const file : File Console.log(...data: any[]): void (+1 overload) Console. log ( ... data: any[]): void ( + 1 overload) Console. log ( ... data: any[]): void ( + 1 overload) The console.log() static method outputs a message to the console. MDN Reference Uint8Array<ArrayBufferLike>.byteLength: number interface Uint8Array < ArrayBufferLike > {
byteLength : number ;
} interface Uint8Array <
ArrayBufferLike ,
> {
byteLength : number ;
} The length in bytes of the array.