From 2400a54a650a1ab78afee683d6580e566e0b4565 Mon Sep 17 00:00:00 2001 From: Paolo Tosco Date: Wed, 15 Oct 2025 13:02:04 +0200 Subject: [PATCH] address #8840 by implementing dpi parameter in PandasTools.SaveXlsxFromFrame() (#8841) Co-authored-by: ptosco --- rdkit/Chem/PandasTools.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/rdkit/Chem/PandasTools.py b/rdkit/Chem/PandasTools.py index 38e7e6284..173d8c86c 100644 --- a/rdkit/Chem/PandasTools.py +++ b/rdkit/Chem/PandasTools.py @@ -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()