[GH-ISSUE #495] Feature: Allow setting column widths not snapped to pixel grid #387

Closed
opened 2026-05-05 12:14:16 -06:00 by gitea-mirror · 4 comments
Owner

Originally created by @desttinghim on GitHub (Nov 12, 2025).
Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/495

I was trying to match the formatting of an existing excel report in an internal application I am working on. When trying to match the column widths, I couldn't get the size to exactly match. After digging around in the code and analyzing the logic, I realized that the current code is snapping column widths to integer pixel coordinates. This seems to be an arbitrary limitation and existing XLSX files appear to use subpixel widths. Snapping to pixel widths seems like a good default, so I propose adding new functions for setting column widths. These are the functions I propose adding:

/**
 * @brief Set the properties for one or more columns of cells.
 *
 * @param worksheet Pointer to a lxw_worksheet instance to be updated.
 * @param first_col The zero indexed first column.
 * @param last_col  The zero indexed last column.
 * @param raw_width The total width of each column in fractional character count.
 * @param format    A pointer to a Format instance or NULL.
 *
 * @return A #lxw_error code.
 */
lxw_error worksheet_set_column_raw(lxw_worksheet *worksheet,
                               lxw_col_t first_col,
                               lxw_col_t last_col,
                               double raw_width, lxw_format *format);
/**
 * @brief Set the properties for one or more columns of cells.
 *
 * @param worksheet Pointer to a lxw_worksheet instance to be updated.
 * @param first_col  The zero indexed first column.
 * @param last_col   The zero indexed last column.
 * @param inch_width The total width of each column in inches (25.4 mm).
 * @param format     A pointer to a Format instance or NULL.
 *
 * @return A #lxw_error code.
 */
lxw_error worksheet_set_column_inch(lxw_worksheet *worksheet,
                               lxw_col_t first_col,
                               lxw_col_t last_col,
                               double inch_width, lxw_format *format);
/**
 * @brief Set the properties for one or more columns of cells.
 *
 * @param worksheet Pointer to a lxw_worksheet instance to be updated.
 * @param first_col The zero indexed first column.
 * @param last_col  The zero indexed last column.
 * @param pt_width  The total width of each column in points (1/72 of an inch).
 * @param format    A pointer to a Format instance or NULL.
 *
 * @return A #lxw_error code.
 */
lxw_error worksheet_set_column_pt(lxw_worksheet *worksheet,
                               lxw_col_t first_col,
                               lxw_col_t last_col,
                               double pt_width, lxw_format *format);
/**
 * @brief Set the properties for one or more columns of cells.
 *
 * @param worksheet Pointer to a lxw_worksheet instance to be updated.
 * @param first_col The zero indexed first column.
 * @param last_col  The zero indexed last column.
 * @param mm_width  The total width of each column in millimeters.
 * @param format    A pointer to a Format instance or NULL.
 *
 * @return A #lxw_error code.
 */
lxw_error worksheet_set_column_mm(lxw_worksheet *worksheet,
                               lxw_col_t first_col,
                               lxw_col_t last_col,
                               double mm_width, lxw_format *format);
  • When I say "total width", I'm including padding
  • The spec doesn't include a way to actually specify sizing inch, pt, and mm, so we'd have to first convert to pixels (1 character = 7 pixels by default), and then convert to inches, points, and mm (96 pixels = 1 inch = 72 points = 25.4 mm)
  • I think 96 DPI is the correct metric

Out of the four proposed functions, only the _raw variant is really necessary, the others are easy enough write wrapper functions for if it is implemented.

Originally created by @desttinghim on GitHub (Nov 12, 2025). Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/495 I was trying to match the formatting of an existing excel report in an internal application I am working on. When trying to match the column widths, I couldn't get the size to exactly match. After digging around in the code and analyzing the logic, I realized that the current code is snapping column widths to integer pixel coordinates. This seems to be an arbitrary limitation and existing XLSX files appear to use subpixel widths. Snapping to pixel widths seems like a good default, so I propose adding new functions for setting column widths. These are the functions I propose adding: ```C /** * @brief Set the properties for one or more columns of cells. * * @param worksheet Pointer to a lxw_worksheet instance to be updated. * @param first_col The zero indexed first column. * @param last_col The zero indexed last column. * @param raw_width The total width of each column in fractional character count. * @param format A pointer to a Format instance or NULL. * * @return A #lxw_error code. */ lxw_error worksheet_set_column_raw(lxw_worksheet *worksheet, lxw_col_t first_col, lxw_col_t last_col, double raw_width, lxw_format *format); /** * @brief Set the properties for one or more columns of cells. * * @param worksheet Pointer to a lxw_worksheet instance to be updated. * @param first_col The zero indexed first column. * @param last_col The zero indexed last column. * @param inch_width The total width of each column in inches (25.4 mm). * @param format A pointer to a Format instance or NULL. * * @return A #lxw_error code. */ lxw_error worksheet_set_column_inch(lxw_worksheet *worksheet, lxw_col_t first_col, lxw_col_t last_col, double inch_width, lxw_format *format); /** * @brief Set the properties for one or more columns of cells. * * @param worksheet Pointer to a lxw_worksheet instance to be updated. * @param first_col The zero indexed first column. * @param last_col The zero indexed last column. * @param pt_width The total width of each column in points (1/72 of an inch). * @param format A pointer to a Format instance or NULL. * * @return A #lxw_error code. */ lxw_error worksheet_set_column_pt(lxw_worksheet *worksheet, lxw_col_t first_col, lxw_col_t last_col, double pt_width, lxw_format *format); /** * @brief Set the properties for one or more columns of cells. * * @param worksheet Pointer to a lxw_worksheet instance to be updated. * @param first_col The zero indexed first column. * @param last_col The zero indexed last column. * @param mm_width The total width of each column in millimeters. * @param format A pointer to a Format instance or NULL. * * @return A #lxw_error code. */ lxw_error worksheet_set_column_mm(lxw_worksheet *worksheet, lxw_col_t first_col, lxw_col_t last_col, double mm_width, lxw_format *format); ``` - When I say "total width", I'm including padding - The spec doesn't include a way to actually specify sizing inch, pt, and mm, so we'd have to first convert to pixels (1 character = 7 pixels by default), and then convert to inches, points, and mm (96 pixels = 1 inch = 72 points = 25.4 mm) - I think 96 DPI is the correct metric Out of the four proposed functions, only the _raw variant is really necessary, the others are easy enough write wrapper functions for if it is implemented.
Author
Owner

@jmcnamara commented on GitHub (Nov 12, 2025):

existing XLSX files appear to use subpixel widths.

I have never seen that, at least not in files generated by Excel.

You can verify that Excel uses pixel widths by trying to set an arbitrary width that doesn't snap to the nearest pixel.

If your target file was created in Excel then it is possible that you are seeing an artifact of how Excel on macOS render widths differently than Excel on Windows. Mac users of Excel (outside of libxlsxwriter) often complain about that since it can change image dimensions.

If you have or can create a sample file to demonstrate what you mean then please upload it.

<!-- gh-comment-id:3519364569 --> @jmcnamara commented on GitHub (Nov 12, 2025): > existing XLSX files appear to use subpixel widths. I have never seen that, at least not in files generated by Excel. You can verify that Excel uses pixel widths by trying to set an arbitrary width that doesn't snap to the nearest pixel. If your target file was created in Excel then it is possible that you are seeing an artifact of how Excel on macOS render widths differently than Excel on Windows. Mac users of Excel (outside of libxlsxwriter) often complain about that since it can change image dimensions. If you have or can create a sample file to demonstrate what you mean then please upload it.
Author
Owner

@desttinghim commented on GitHub (Nov 12, 2025):

I have never seen that, at least not in files generated by Excel.

You can verify that Excel uses pixel widths by trying to set an arbitrary width that doesn't snap to the nearest pixel.

The excel file I am looking at was generated by another program, so it's possible that is the root of the issue. Oh, I probably should mention I've been viewing the files mostly with libreoffice, but the file was not created or modified with libreoffice. I'm not sure if I can upload the file, I'll have to get back to you on that.

<!-- gh-comment-id:3519483079 --> @desttinghim commented on GitHub (Nov 12, 2025): > I have never seen that, at least not in files generated by Excel. > > You can verify that Excel uses pixel widths by trying to set an arbitrary width that doesn't snap to the nearest pixel. The excel file I am looking at was generated by another program, so it's possible that is the root of the issue. Oh, I probably should mention I've been viewing the files mostly with libreoffice, but the file was not created or modified with libreoffice. I'm not sure if I can upload the file, I'll have to get back to you on that.
Author
Owner

@jmcnamara commented on GitHub (Nov 12, 2025):

I'm not sure if I can upload the file, I'll have to get back to you on that.

No worries. If it wasn't generated by Excel it won't be useful.

<!-- gh-comment-id:3519500717 --> @jmcnamara commented on GitHub (Nov 12, 2025): > I'm not sure if I can upload the file, I'll have to get back to you on that. No worries. If it wasn't generated by Excel it won't be useful.
Author
Owner

@jmcnamara commented on GitHub (Nov 16, 2025):

I'm going to close this because Excel uses pixel precision for positioning and libxlsxwriter needs to adhere to that.

<!-- gh-comment-id:3539442064 --> @jmcnamara commented on GitHub (Nov 16, 2025): I'm going to close this because Excel uses pixel precision for positioning and libxlsxwriter needs to adhere to that.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/libxlsxwriter#387
No description provided.