Openpyxl 的 xml 更改破坏了我的工作簿。我需要修复或替代方案
Openpyxl's xml changes break my workbook. I need a fix or alternative
我有一个非常大的 .xlsm 用作模板。工作簿的其余部分会查看工作簿中的 4 个空白选项卡。这些 sheet 都是文本格式,不需要其他格式。我有一个程序:
- 执行 SQL 查询,
- 根据我的输入复制并重命名模板,
- 用我的查询数据填充这 4 个选项卡,(openpyxl)
- 保存笔记本。(openpyxl)
我最近引入了新版本的模板,现在打开输出文件时出现以下错误(告诉excel它可以恢复笔记本。)
Replaced Part: /xl/worksheets/sheet31.xml part with XML error. The namespace for 'xmlns:xml' is reserved and it can only be declared as 'http://www.w3.org/XML/1998/namespace'. Line 8, column 90.
我在 xml 中发现了有关 sheet 的问题。
如果我走这条线:
</f><v></v></c><c r="E2" s="132"><f xmlns:ns0="http://www.w3.org/XML/1998/namespace" aca="1" ca="1" ref="E2" t="array" ns0:space="preserve">
我将其更新为:
</f><v></v></c><c r="E2" s="132"><f aca="1" ca="1" ref="E2" t="array" xml:space="preserve">
...我可以毫无问题地打开它!
将 sheet 的模板 xml 与 openpyxl 输出的内容进行比较,我确信它基本上重写了整个笔记本,因为它最了解问题所在。 我需要一个能够简单地写入这些选项卡并保持笔记本其余部分完好无损的替代方案,或者我需要知道 openpyxl code/commands 本身是否有我可以使用的东西改变以避免这种情况。
值得注意的是 xml 所在的单元格是一个数组公式,它以另一个选项卡上的命名范围为目标(笔记本中其他地方存在的东西),如果我删除该公式或在模板中删除它的某些部分,导出的文件完全可以打开,但这是为了测试而完成的,我没有尝试过任何解决方法,因为公式是安全的,不会出错。
编辑:
我已验证公式中没有尾随空格,甚至尝试在任何输出中删除空格。错误仍然存在。
这是单元格中会出现 xml 错误的公式:
{=
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
IF(A2="","",IFERROR(VLOOKUP($A2&"|"&$C2,INDIRECT("'"&INDEX(Lookup_sheets,MATCH(1,--(COUNTIF(INDIRECT("'"&Lookup_sheets&"'!$T:$T"),$A2&"|"&$C2)>0),0))&"'!$T:$U"),2,FALSE),"NOT FOUND")),
INDEX(SIMP_CONF_FIND,1),INDEX(SIMP_CONF_REP,1)),
INDEX(SIMP_CONF_FIND,2),INDEX(SIMP_CONF_REP,2)),
INDEX(SIMP_CONF_FIND,3),INDEX(SIMP_CONF_REP,3)),
INDEX(SIMP_CONF_FIND,4),INDEX(SIMP_CONF_REP,4))}
所以,删除公式中的所有尾随空格,以及公式中的所有换行符似乎已经解决了问题!我不明白,因为我在很多其他地方都有换行符,包括其他数组公式,但在这里修复了它。
编辑:
对我有其他带换行符的公式感到非常沮丧,我去看看所有其他公式和这个特定公式之间是否有区别,发现这是 sheet 中我有一行的唯一公式-break 紧跟在第一个“=”之后。一旦我将它更新为以下公式,它就起作用了,而且我能够保留我的换行符!
{=SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
IF(A2="","",IFERROR(VLOOKUP($A2&"|"&$C2,INDIRECT("'"&INDEX(Lookup_sheets,MATCH(1,--(COUNTIF(INDIRECT("'"&Lookup_sheets&"'!$T:$T"),$A2&"|"&$C2)>0),0))&"'!$T:$U"),2,FALSE),"NOT FOUND")),
INDEX(SIMP_CONF_FIND,1),INDEX(SIMP_CONF_REP,1)),
INDEX(SIMP_CONF_FIND,2),INDEX(SIMP_CONF_REP,2)),
INDEX(SIMP_CONF_FIND,3),INDEX(SIMP_CONF_REP,3)),
INDEX(SIMP_CONF_FIND,4),INDEX(SIMP_CONF_REP,4))}
感谢 Charlie Clark 将我的大脑指向我在所有故障排除过程中尚未尝试过的一种组合!
我有一个非常大的 .xlsm 用作模板。工作簿的其余部分会查看工作簿中的 4 个空白选项卡。这些 sheet 都是文本格式,不需要其他格式。我有一个程序:
- 执行 SQL 查询,
- 根据我的输入复制并重命名模板,
- 用我的查询数据填充这 4 个选项卡,(openpyxl)
- 保存笔记本。(openpyxl)
我最近引入了新版本的模板,现在打开输出文件时出现以下错误(告诉excel它可以恢复笔记本。)
Replaced Part: /xl/worksheets/sheet31.xml part with XML error. The namespace for 'xmlns:xml' is reserved and it can only be declared as 'http://www.w3.org/XML/1998/namespace'. Line 8, column 90.
我在 xml 中发现了有关 sheet 的问题。
如果我走这条线:
</f><v></v></c><c r="E2" s="132"><f xmlns:ns0="http://www.w3.org/XML/1998/namespace" aca="1" ca="1" ref="E2" t="array" ns0:space="preserve">
我将其更新为:
</f><v></v></c><c r="E2" s="132"><f aca="1" ca="1" ref="E2" t="array" xml:space="preserve">
...我可以毫无问题地打开它!
将 sheet 的模板 xml 与 openpyxl 输出的内容进行比较,我确信它基本上重写了整个笔记本,因为它最了解问题所在。 我需要一个能够简单地写入这些选项卡并保持笔记本其余部分完好无损的替代方案,或者我需要知道 openpyxl code/commands 本身是否有我可以使用的东西改变以避免这种情况。
值得注意的是 xml 所在的单元格是一个数组公式,它以另一个选项卡上的命名范围为目标(笔记本中其他地方存在的东西),如果我删除该公式或在模板中删除它的某些部分,导出的文件完全可以打开,但这是为了测试而完成的,我没有尝试过任何解决方法,因为公式是安全的,不会出错。
编辑: 我已验证公式中没有尾随空格,甚至尝试在任何输出中删除空格。错误仍然存在。
这是单元格中会出现 xml 错误的公式:
{=
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
IF(A2="","",IFERROR(VLOOKUP($A2&"|"&$C2,INDIRECT("'"&INDEX(Lookup_sheets,MATCH(1,--(COUNTIF(INDIRECT("'"&Lookup_sheets&"'!$T:$T"),$A2&"|"&$C2)>0),0))&"'!$T:$U"),2,FALSE),"NOT FOUND")),
INDEX(SIMP_CONF_FIND,1),INDEX(SIMP_CONF_REP,1)),
INDEX(SIMP_CONF_FIND,2),INDEX(SIMP_CONF_REP,2)),
INDEX(SIMP_CONF_FIND,3),INDEX(SIMP_CONF_REP,3)),
INDEX(SIMP_CONF_FIND,4),INDEX(SIMP_CONF_REP,4))}
所以,删除公式中的所有尾随空格,以及公式中的所有换行符似乎已经解决了问题!我不明白,因为我在很多其他地方都有换行符,包括其他数组公式,但在这里修复了它。
编辑: 对我有其他带换行符的公式感到非常沮丧,我去看看所有其他公式和这个特定公式之间是否有区别,发现这是 sheet 中我有一行的唯一公式-break 紧跟在第一个“=”之后。一旦我将它更新为以下公式,它就起作用了,而且我能够保留我的换行符!
{=SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
IF(A2="","",IFERROR(VLOOKUP($A2&"|"&$C2,INDIRECT("'"&INDEX(Lookup_sheets,MATCH(1,--(COUNTIF(INDIRECT("'"&Lookup_sheets&"'!$T:$T"),$A2&"|"&$C2)>0),0))&"'!$T:$U"),2,FALSE),"NOT FOUND")),
INDEX(SIMP_CONF_FIND,1),INDEX(SIMP_CONF_REP,1)),
INDEX(SIMP_CONF_FIND,2),INDEX(SIMP_CONF_REP,2)),
INDEX(SIMP_CONF_FIND,3),INDEX(SIMP_CONF_REP,3)),
INDEX(SIMP_CONF_FIND,4),INDEX(SIMP_CONF_REP,4))}
感谢 Charlie Clark 将我的大脑指向我在所有故障排除过程中尚未尝试过的一种组合!