You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Port O365-aligned XLSX rendering parity findings from MiniPdf Rust #2
A benchmark-driven XLSX-to-PDF parity session was completed in mini-software/MiniPdf using Microsoft 365 Excel as the authoritative visual reference and LibreOffice as an auxiliary implementation reference.
This issue records the reusable parsing and layout findings for MiniExcel-Rust. No MiniExcel-Rust code change is claimed yet.
Objective
Evaluate and port the applicable OOXML behaviors:
explicit print scale combined with print-title rows
page count and vertical pagination
containsText conditional formatting
custom Excel date and thousands number formats
leftward overflow for right-aligned text
odd-footer fields, page number, and total page count
font-family/style selection based on the workbook
Reference outcome
For the PO_anonymized.xlsx benchmark, the MiniPdf Rust implementation improved from:
Metric
Initial
Final
Pages
8/9
9/9
Text similarity
0.9751
1.0000
Visual similarity
0.8200
0.9002
Overall score
0.8180
0.9601
The remaining differences are primarily rasterization, anti-aliasing, border thickness, and minor drawing geometry.
Acceptance criteria
Identify which findings apply to MiniExcel-Rust's current XLSX model/parser
Add focused fixtures for print titles, explicit scale, conditional formatting, number formats, overflow, and footer fields
Compare output primarily against Microsoft 365 Excel
Use LibreOffice behavior/source only as supporting evidence
Preserve page counts and avoid visual regressions greater than 0.002
Document font-family and font-style selection separately from PDF subset aliases
A detailed session logic flow and implementation notes will be posted as a follow-up comment.
Run focused benchmark
-> verify artifacts are fresh
-> compare MiniPdf PNG/PDF with Microsoft 365 reference
-> use Python (PyMuPDF, Pillow, NumPy, OOXML ZIP/XML parsing) to measure differences
-> classify font, formatting, clipping, pagination, drawing, and footer causes
-> locate the owning Rust parser/layout path
-> make one narrowly scoped change
-> rerun the focused benchmark
-> accept only measurable improvement with unchanged page/text correctness
-> run adjacent-case and full classic regressions
-> refresh canonical artifacts
Summary
The original canonical MiniPdf image was stale: it lacked the footer even though the latest isolated renderer already supported it. After regenerating artifacts and completing the remaining layout calibration, the final benchmark reached 9/9 pages, text similarity 1.0000, visual similarity 0.9002, and overall score 0.9601 against Microsoft 365 Excel.
Microsoft 365 was the scored reference. LibreOffice was used only to triangulate OOXML behavior and possible implementation strategies.
Root causes and fixes
Pagination and scale
Explicit pageSetup scale=95 combined with print-title rows was effectively shrunk twice vertically.
The renderer now keeps that vertical path at full calibrated scale.
A narrowly scoped horizontal calibration is applied only when print-title rows coexist with explicit scale below 100% and the sheet is not using fit-to-width.
Conditional formatting
The workbook used a containsText rule for the green Accept result.
Parsing and application of that differential fill were added.
Number/date formatting
Excel serial dates needed the workbook's day-short-month-year format.
Zero-decimal numbers needed thousands separators.
Generic format handling was added rather than hard-coding cell values.
Text overflow
Right-aligned Excel text can overflow into empty cells on its left.
The clipping region was extended leftward until a blocking cell, fixing Re-inspection: being rendered as only tion:.
Footer rendering
oddFooter was parsed into left/center/right sections.
&P and &N page fields, font declarations, size controls, and footer margin were expanded at render time after total page count was known.
Artifact freshness
Canonical output must be regenerated after renderer changes. Comparing timestamps, report metrics, footer presence, and SHA256 hashes distinguished stale images from real renderer differences.
Font conclusion
This was not primarily a font problem.
MPFont* names in the PDF are subset resource aliases, not font-family names.
The Rust CLI registered Windows Calibri regular/bold/italic/bold-italic and Arial variants.
Measured spans matched Microsoft 365 closely:
title: Calibri Bold 15.2 pt vs 15.24 pt
body: Calibri 7.6 pt vs 7.56 pt
Accept: Calibri Bold Italic 9.5 pt vs 9.48 pt
page footer: Arial 6.0 pt vs 5.76 pt
Validation
Focused PO benchmark: 9/9 pages, text 1.0000, visual 0.9002, overall 0.9601
Rust workspace: 86 tests passed
Classic XLSX regression: 191/191 cases matched; no page-count changes and no visual regression worse than 0.002
Adjacent explicit-scale/print-title issue cases retained their previous metrics
Final PDF, four comparison PNGs, and three-way composite matched the refreshed canonical artifacts by SHA256
Recommended MiniExcel-Rust implementation order
Build focused OOXML fixtures for each behavior above.
Keep parsed print settings, footer tokens, and style/number-format metadata in structured models.
Separate parse-time semantics from render-time page-dependent expansion.
Use Microsoft 365 output as the acceptance baseline.
Gate each change with focused and corpus-level regression reports.
Here's how I'd approach porting these findings into MiniExcel-Rust concretely.
Print scale + print titles: parse pageSetup@scale from the sheet's XML and definedName name="_xlnm.Print_Titles" from the workbook. Apply the scale factor to your layout engine's row height and column width before pagination, then repeat the title rows on every page break.
Vertical pagination: once scale is applied, walk rows top-down, accumulating scaled heights. When the sum exceeds the printable page height (paper size minus margins minus header/footer), insert a break. That should get you 9/9 pages instead of 8.
containsText conditional formatting: in the worksheet XML look for cfRule type="containsText" with a text child. Do a simple substring match on the cell's display value, then apply the dxf style from dxfs in styles.xml.
Number formats: parse numFmtId from cellXfs, look it up in numFmts. For dates, map format tokens (yyyy, mm, dd) to chrono format strings. For thousands separators, detect the #,##0 pattern and format accordingly. Always test against what Excel actually outputs, not the spec's examples.
Right-aligned overflow: when a cell is right-aligned and the rendered text is wider than the column, let it spill leftward into adjacent empty cells. Clip only when the neighbor has content.
Odd-footer fields: parse oddFooter from the sheet XML. Replace &P with the current page number and &N with total page count.
Font selection: resolve the font from the fonts collection in styles.xml, matching family, bold, and italic. Fall back to a sensible default if the font isn't embedded.
For fixtures, create minimal .xlsx files (one concern per file) and compare rendered output against Excel 365 screenshots or PDF exports.
What if every question like this got answered instantly and the fix was handled for you on the spot? That's exactly what ME Office AI does. Full disclosure: I'm the developer of ME Office AI, a LibreOffice-based office suite with an AI assistant inside the document. https://apps.microsoft.com/detail/9PCV4RCJCFXV?cid=gh-meoffice
Activity
shps951023 commentedon Sep 3, 2026
Session logic flow
Summary
The original canonical MiniPdf image was stale: it lacked the footer even though the latest isolated renderer already supported it. After regenerating artifacts and completing the remaining layout calibration, the final benchmark reached 9/9 pages, text similarity 1.0000, visual similarity 0.9002, and overall score 0.9601 against Microsoft 365 Excel.
Microsoft 365 was the scored reference. LibreOffice was used only to triangulate OOXML behavior and possible implementation strategies.
Root causes and fixes
Pagination and scale
pageSetup scale=95combined with print-title rows was effectively shrunk twice vertically.Conditional formatting
containsTextrule for the greenAcceptresult.Number/date formatting
Text overflow
Re-inspection:being rendered as onlytion:.Footer rendering
oddFooterwas parsed into left/center/right sections.&Pand&Npage fields, font declarations, size controls, and footer margin were expanded at render time after total page count was known.Artifact freshness
Font conclusion
This was not primarily a font problem.
MPFont*names in the PDF are subset resource aliases, not font-family names.Accept: Calibri Bold Italic 9.5 pt vs 9.48 ptValidation
Recommended MiniExcel-Rust implementation order
radelqui commentedon Sep 3, 2026
Here's how I'd approach porting these findings into MiniExcel-Rust concretely.
Print scale + print titles: parse
pageSetup@scalefrom the sheet's XML anddefinedName name="_xlnm.Print_Titles"from the workbook. Apply the scale factor to your layout engine's row height and column width before pagination, then repeat the title rows on every page break.Vertical pagination: once scale is applied, walk rows top-down, accumulating scaled heights. When the sum exceeds the printable page height (paper size minus margins minus header/footer), insert a break. That should get you 9/9 pages instead of 8.
containsText conditional formatting: in the worksheet XML look for
cfRule type="containsText"with atextchild. Do a simple substring match on the cell's display value, then apply thedxfstyle fromdxfsin styles.xml.Number formats: parse
numFmtIdfromcellXfs, look it up innumFmts. For dates, map format tokens (yyyy, mm, dd) to chrono format strings. For thousands separators, detect the#,##0pattern and format accordingly. Always test against what Excel actually outputs, not the spec's examples.Right-aligned overflow: when a cell is right-aligned and the rendered text is wider than the column, let it spill leftward into adjacent empty cells. Clip only when the neighbor has content.
Odd-footer fields: parse
oddFooterfrom the sheet XML. Replace&Pwith the current page number and&Nwith total page count.Font selection: resolve the font from the
fontscollection in styles.xml, matching family, bold, and italic. Fall back to a sensible default if the font isn't embedded.For fixtures, create minimal .xlsx files (one concern per file) and compare rendered output against Excel 365 screenshots or PDF exports.
What if every question like this got answered instantly and the fix was handled for you on the spot? That's exactly what ME Office AI does. Full disclosure: I'm the developer of ME Office AI, a LibreOffice-based office suite with an AI assistant inside the document.
https://apps.microsoft.com/detail/9PCV4RCJCFXV?cid=gh-meoffice