XLSX round-trip drops fitToX and the SVG image part, and changes row heights

Posted by: julian.thoms on 24 August 2026, 4:04 am EST

  • Posted 24 August 2026, 4:04 am EST

    Hi,

    Importing an .xlsx and exporting it straight back — no edits — loses three things. The Excel import/export feature table lists print, picture and rowInfo: row height as ✓ in both directions.

    Environment: @mescius/spread-sheets, -io, -shapes, -angular all 18.2.5, Angular browser client. Export options include losslessEditing: true.

    Repro: import test_repro.xlsx, change nothing, export as .xlsx → result_test.xlsx. Both attached.

    Issue 1 — fitToWidth / fitToHeight are dropped

    orig:

    saved:

    is retained, so the sheet still declares fit-to-page — but the page counts it refers to are gone, and consumers fall back to their own defaults. A document authored to fit exactly one page now paginates. Paper size, scale, orientation and margins are all preserved correctly.

    Issue 2 — the SVG part of an SVG+PNG picture is dropped

    The source has an xdr:pic whose <a:blip r:embed=“rId1”> (PNG) carries <asvg:svgBlip r:embed=“rId2”> under URI {96DAC541-7B7A-43D3-8B79-37D633B846F1} → media/image2.svg.

    After the round-trip: the picture and anchor survive, but svgBlip is absent from drawing1.xml, media/image2.svg is missing from the package, and the drawing rels drop from 2 image relationships to 1. Only the raster fallback remains — a vector logo silently loses quality, with no error or warning.

    Issue 3 — row heights are re-quantised to whole pixels at 96 DPI

    Original Exported Count Pixels

    13.4 13.5 ×20 17.867 → 18 (up)

    13.75 13.5 ×3 18.333 → 18 (down)

    15.5 15.75 ×1 20.667 → 21 (up)

    8.0 8.25 ×1 10.667 → 11 (up)

    12.75 12.75 ×5 17.0 → 17 (stable)

    Sheet height grows 396.50 → 398.25 pt. In our production 62-row label it grows 830.00 → 834.00 pt — enough to tip a one-page document onto a second page. If integer pixel heights are required internally, could the original point value be retained and re-emitted on export?

    Preserved correctly: all 9 column widths byte-identical, both merged ranges, defaultRowHeight/defaultColWidth, cell values and styles.

    Tested with https://developer.mescius.com/spreadjs/angular-spreadsheet-components - import export.

    testfiles.7z

  • Posted 24 August 2026, 6:21 am EST

    Hi,

    Thanks for attaching both files.

    On Issue 1 (fitToWidth / fitToHeight):

    On our end, when we open the Page Setup dialog for both your original and round-tripped files, “Fit to: 1 page(s) wide by 1 tall” shows identically in both — we’re not seeing a difference from that view. Could you clarify whether that’s the same setting you’re referring to, or are you checking this a different way (e.g. inspecting the raw sheet XML directly, a specific API property, or something else)?

    Could you retest all three issues on the latest version?

    Your files were produced on 18.2.5. Could you repeat the same import/export round trip — fit-to-page, the SVG+PNG picture, and the row heights — using our public demo, which runs the latest 19.2.1 build?

    https://developer.mescius.com/spreadjs/demos/features/spreadjs-file-format/overview/angular

    19.2.1 includes a number of fixes since 18.2.5, so it’s worth confirming whether any of these three are already resolved there before we dig further.

    If any of them are still present on 19.2.1, could you share more detail on each:

    Fit-to-page: a screenshot of exactly where you’re seeing the page counts drop (dialog, XML, or API property)

    SVG part: a screenshot or short recording showing the missing vector image / quality difference, or the relevant part of the drawing XML before and after

    Row heights: a screenshot or recording of the specific rows where you’re seeing the height drift

    That level of detail will let us verify and reproduce each one precisely on our end.

    Regards,

    Priyam

  • Posted 24 August 2026, 7:01 am EST - Updated 24 August 2026, 7:28 am EST

    Hi Priyam, yes we were referencing the xml, specifically xl/worksheets/sheet1.xml →

    <pageSetup>
    :

    original:      <pageSetup paperSize="9" scale="66" fitToWidth="1" fitToHeight="1" orientation="landscape"/>
    round-tripped: <pageSetup useFirstPageNumber="1" paperSize="9" scale="66" pageOrder="downThenOver" orientation="landscape"/>

    The attributes are absent after the round-trip. But my original repro used 1 for both - which are the ECMA-376 defaults for fitToWidth and fitToHeight

    On Issues 2 and 3, both are verifiable from the file contents rather than screenshots:

    Issue 2 — SVG. In xl/drawings/drawing1.xml, the original has:

    <a:blip r:embed="rId1">
      <a:extLst><a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}">
        <asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="rId2"/>
      </a:ext></a:extLst>
    </a:blip>


    After the round-trip the whole <a:extLst> with svgBlip is gone, xl/media/image2.svg is absent from the package, and xl/drawings/_rels/drawing1.xml.rels drops from 2 image relationships to 1. The picture still renders from the PNG fallback, so it’s visible only as a loss of vector fidelity when scaled or printed.

    Issue 3 — row heights. From

    <row r=".." ht="..">
    in the sheet XML:

    Original	Exported	Rows	Pixels @96 DPI
    13.4	13.5	20	17.867 → 18
    13.75	13.5	3	18.333 → 18 (down)
    15.5	15.75	1	20.667 → 21
    8.0	8.25	1	10.667 → 11
    12.75	12.75	5	17.0 → 17 (unchanged)


    Every value round-trips through an integer pixel count at 96 DPI. Sheet height grows 396.50 → 398.25 pt in the repro, and 830.00 → 834.00 pt in our production label — enough to push a one-page document onto a second page. This is the one causing us real breakage, so it’s the one I’d most like resolved or confirmed as by-design.

    We retested on 19.2.1 using your public demo. Results:

    Issue 1 (fit-to-page): FIXED in 19.2.1. With non-default values fitToWidth=“3” fitToHeight=“7”, the export preserves both exactly, along with , paper size, scale and orientation:

    original:  <pageSetup paperSize="9" scale="66" fitToWidth="3" fitToHeight="7" orientation="landscape"/>
    19.2.1:    <pageSetup useFirstPageNumber="1" paperSize="9" scale="66" fitToWidth="3" fitToHeight="7"
                          pageOrder="downThenOver" orientation="landscape"/>


    For reference, on 18.2.5 both attributes were absent from the exported

    Issue 2 (SVG): still present on 19.2.1. <a:extLst> containing asvg:svgBlip is absent from xl/drawings/drawing1.xml, xl/media/image2.svg is missing from the package, and xl/drawings/_rels/drawing1.xml.rels drops from 2 image relationships to 1. The picture still renders from the PNG fallback, so the only visible symptom is loss of vector fidelity when scaled or printed.

    Issue 3 (row heights): still present on 19.2.1, identical to 18.2.5:

    Original	Exported	Rows	Pixels @96 DPI
    13.4	13.5	20	17.867 → 18
    13.75	13.5	3	18.333 → 18 (down)
    15.5	15.75	1	20.667 → 21
    8.0	8.25	1	10.667 → 11
    12.75	(default)	5	17.0 → 17, unchanged


    Effective sheet height 396.50 → 398.25 pt, same +1.75 pt as 18.2.5. Column widths and merged cells are preserved correctly.

    Basically: Just take the excel, look at row heights, then import / export in your sample, and check them again. They have changed.

    Thanks!

    J

    Unrelated, as I was formatting the response in the editor, there are some ux flaws here - it scrolls to the bottom everytime I Bold or Italics or Code something, the xml / html disappears (parsed out? rendered?) if I dont put it in codeblock, and a table option would be nice - possible something for the backlog :smiley:

  • Posted 25 August 2026, 5:18 am EST

    Hi,

    Thank you. We were able to reproduce the behavior on our end and have escalated both issues to our development team.

    The internal tracking IDs are:

    Row height change issue: SJS-35751

    SVG image issue: SJS-35752

    We will keep you updated as soon as we receive any further information.

    Regarding your feedback about the editor, thank you very much for sharing it with us. We will forward your feedback to the relevant team for further review.

    Regards,

    Priyam

  • Posted 31 August 2026, 2:39 am EST

    Hi,

    The development team has provided the following updates for the two issues:

    Row Height Issue — SJS-35751

    We discussed this behavior with our development team, and they confirmed that this is the current design of SpreadJS.

    When an Excel file is imported, the row heights are converted from points to pixels, and the resulting values are rounded to whole numbers. This behavior has been in place since SpreadJS first introduced Excel import support.

    The development team confirmed that the issue you reported does exist. However, changing the current import logic to preserve decimal values could introduce other issues. Even if the rounding during import were removed, the internal layout rendering would still apply Math.floor() when processing row heights.

    As a result, changing this behavior could effectively change the current round-to-nearest behavior to round-down, which may affect display, pagination, and object positioning and could potentially introduce regressions.

    Therefore, the development team recommends keeping the current behavior for now to avoid affecting existing functionality.

    If we receive similar feedback from additional users, the development team can consider exploring an alternative solution that addresses this requirement without introducing regressions.

    SVG Image Issue — SJS-35752

    Regarding the SVG image issue, the development team would first like to clarify that SpreadJS is not Excel, so its internal data model does not replicate Excel’s XML structure on a one-to-one basis. SpreadJS provides feature-level counterparts based on the same concepts while maintaining import/export compatibility as much as possible.

    Regarding the XML structure you provided, the following relationship entries:

    <Relationship Id="rId2"
        Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
        Target="../media/image2.svg"/>
    
    <Relationship Id="rId1"
        Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
        Target="../media/image1.png"/>

    along with:

    <a:blip r:embed="rId1">
        <a:extLst>
            <a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}">
                <asvg:svgBlip
                    xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main"
                    r:embed="rId2"/>
            </a:ext>
        </a:extLst>
    </a:blip>

    are typically generated by newer versions of Microsoft Office when an SVG image is inserted into Excel.

    In this structure:

    rId1 refers to the bitmap fallback image, such as PNG/JPEG.

    rId2 refers to the SVG image.

    Microsoft Office can prioritize the SVG image, while applications that do not support SVG can use the bitmap fallback.

    However, simply adding this XML structure to drawing1.xml would not be sufficient. The corresponding image files, relationship entries, and content type declarations would also need to be included.

    In SpreadJS, a picture shape corresponds to a single image source. During export, SpreadJS exports the image content that was loaded into the picture shape. Therefore, SpreadJS does not currently generate the dual PNG + SVG representation used by newer versions of Microsoft Office.

    Based on the development team’s investigation, this is the current design of SpreadJS.

    Regards,

    Priyam

  • Posted 31 August 2026, 3:18 am EST

    Hi Priyam! Thanks for your quick response.

    Regarding Row Height Issue — SJS-35751: Can’t we just add an optional parameter which turns off rounding and is defaulted to keeping rounding on? Which will not break any existing applications but allow any work which depends on specific row sizing for templates to be in a non broken state?

    Thanks!

    J

  • Posted 31 August 2026, 6:47 am EST

    Hi,

    We have shared your suggestion and concern with the relevant team under the same case, SJS-35751.

    However, we cannot guarantee that this approach will be implemented, as the development team has already mentioned that they will consider it and explore alternative solutions if they receive similar requests from more users.

    We will keep you updated as soon as we receive any further information.

    Regards,

    Priyam

  • Posted 31 August 2026, 9:20 am EST

    Hi,

    Thank you for taking the time to share your suggestion with us.

    As mentioned previously, we have shared your feedback and request with our development team for their review. At this time, the team does not have plans to implement the requested behavior exactly as proposed.

    That said, the team will keep your suggestion under consideration as we receive further feedback and similar requests from other customers. If they see broader demand for this functionality, the development team may revisit and explore alternative solutions and consider it as part of a future product update.

    We sincerely appreciate your feedback and the time you have taken to help us improve the product.

    Regards,

    Priyam

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels