address #8840 by implementing dpi parameter in PandasTools.SaveXlsxFromFrame() (#8841)

Co-authored-by: ptosco <paolo.tosco@novartis.com>
This commit is contained in:
Paolo Tosco
2025-10-15 13:02:04 +02:00
committed by GitHub
parent af4e8cf01f
commit 2400a54a65

View File

@@ -155,6 +155,7 @@ highlightSubstructures = True
molRepresentation = "png" # supports also SVG
molSize = (200, 200)
molJustify = "center" # supports also left, right
XLSX_DEFAULT_DPI = 96
def _molge(x, y):
@@ -494,7 +495,7 @@ def SaveSMILESFromFrame(frame, outFile, molCol='ROMol', NamesCol='', isomericSmi
w.close()
def SaveXlsxFromFrame(frame, outFile, molCol='ROMol', size=(300, 300), formats=None):
def SaveXlsxFromFrame(frame, outFile, molCol='ROMol', size=(300, 300), dpi=XLSX_DEFAULT_DPI, formats=None):
"""
Saves pandas DataFrame as a xlsx file with embedded images.
molCol can be either a single column label or a list of column labels.
@@ -537,6 +538,8 @@ def SaveXlsxFromFrame(frame, outFile, molCol='ROMol', size=(300, 300), formats=N
format = workbook.add_format(format)
cell_formats[key] = format
worksheet = workbook.add_worksheet() # New work sheet
width_px = size[0] * dpi // XLSX_DEFAULT_DPI
height_px = size[1] * dpi // XLSX_DEFAULT_DPI
# Write first row with column names
for col_idx, col in enumerate(cols):
@@ -551,12 +554,12 @@ def SaveXlsxFromFrame(frame, outFile, molCol='ROMol', size=(300, 300), formats=N
m = row[col]
if isinstance(m, Chem.Mol):
have_img = True
img = Draw.MolToImage(m if isinstance(m, Chem.Mol) else Chem.Mol(), size=size,
img = Draw.MolToImage(m if isinstance(m, Chem.Mol) else Chem.Mol(),
size=(width_px, height_px),
options=drawOptions)
img.save(image_data, format='PNG')
img.save(image_data, format='PNG', dpi=(dpi, dpi))
worksheet.insert_image(row_idx_actual, col_idx, "f", {'image_data': image_data})
worksheet.set_column(col_idx, col_idx,
width=size[0] / 6.) # looks like height is not in px?
worksheet.set_column_pixels(col_idx, col_idx, width=size[0])
continue
if str(dataTypes[col]) == "object":
# string length is limited in xlsx
@@ -568,7 +571,7 @@ def SaveXlsxFromFrame(frame, outFile, molCol='ROMol', size=(300, 300), formats=N
elif 'datetime' in str(dataTypes[col]):
worksheet.write_datetime(row_idx_actual, col_idx, row[col], cell_formats['write_datetime'])
if have_img:
worksheet.set_row(row_idx_actual, height=size[1]) # looks like height is not in px?
worksheet.set_row_pixels(row_idx_actual, height=size[1])
workbook.close()
image_data.close()