Python编辑Business Central导出XLSX时如何保留XML引用?
解决Business Central配置包XLSX编辑后丢失XML引用的问题
问题根源
Business Central配置包的XLSX文件包含自定义XML部件(用于定义数据导入的schema),同时表格与这些XML部件存在绑定关系。你的代码存在两个关键问题导致XML引用丢失:
- 使用
hash(row_index)生成行号,导致行号混乱,破坏表格范围与XML的绑定 - 加载工作簿时可能未保留XML绑定信息,且存在语法错误导致代码逻辑异常
解决方案
1. 纠正代码中的核心错误
- 移除无效的残留代码行
{current_column})") - 替换
hash(row_index)为连续行号,确保数据按顺序填充 - 正确计算表格的最终范围
2. 确保加载工作簿时保留XML绑定
使用data_only=False和keep_links=True参数加载工作簿,保留原文件的XML绑定和部件信息。
3. 保留自定义XML部件
openpyxl默认会保留工作簿的自定义XML部件,只要不手动删除,保存时会自动携带这些部件。
修改后的完整代码
def write_data_to_excel(self, df: pd.DataFrame, file_path: str = None): print(self.boolean_columns) file_path = self._check_path(file_path) # 加载工作簿时保留XML绑定和链接 wb = xl.load_workbook(file_path, data_only=False, keep_links=True) ws = wb.active # 计算最终行号:起始行 + 数据行数 - 1(因为row_index从0开始) final_row = self.start_row + len(df) - 1 new_row_count = final_row for row_index, row in df.iterrows(): current_row = self.start_row + row_index for column_index in range(len(df.columns)): current_column = self.start_column + column_index value = row[df.columns[column_index]] try: if current_column in self.boolean_columns: # 直接使用Python布尔值,openpyxl会转换为Excel原生布尔类型 value = True if value == 1 else False ws.cell(row=current_row, column=current_column, value=value) except IllegalCharacterError as e: print(f"IllegalCharacterError: {e} (row: {current_row}, column: {current_column})") value = self._replace_illegal_characters(value) ws.cell(row=current_row, column=current_column, value=value) except ValueError: value = False if current_column in self.boolean_columns else "" ws.cell(row=current_row, column=current_column, value=value) # 更新表格范围 for table in ws.tables.values(): table.ref = f"A3:CY{new_row_count}" wb.save(file_path)
额外注意事项
- 不要修改原表格的列名、列顺序或表格名称,这些与XML schema直接绑定,修改会导致上传失败
- 确保填充的数据类型与原文件一致(比如布尔值用Excel原生布尔类型,而非字符串)
- 如果修改后仍丢失XML部件,可以手动验证:将XLSX文件解压,检查
xl/customXml/目录下是否存在XML文件,修改后的文件应与原文件保留相同的XML结构
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

