Spire.Office for Python 11.7.0 已正式发布。该版本带来了多项强大功能提升:Spire.Doc 支持通过环境变量配置许可证;Spire.XLS 新增数据模拟分析、切片器及 Excel 转 JSON 支持;Spire.PDF 支持签名域中文本自动适配;Spire.Presentation 支持 License 环境变量配置。
除了这些新功能外,本版本还修复了大量与 Word、Excel、PDF 和 PowerPoint 文件的转换、处理及保存相关的已知问题,提供了更加稳定可靠的使用体验。更多详细信息请见下文。
获取 Spire.Office for Python 11.7.0,请点击:
https://www.e-iceblue.cn/Downloads/Spire-Office-Python.html
Spire.Doc for Python
新功能:
- Spire.Doc 现已支持自动识别并加载以下环境变量中的许可证信息:
SPIRE_OFFICE_LICENSE_KEY
SPIRE_DOC_LICENSE_KEY
SPIRE_LICENSE_KEY
Spire.XLS for Python
新功能:
- 支持数据模拟分析(方案管理器)功能,涵盖创建、编辑、删除、摘要生成及合并。
- 支持通过表格数据添加 Slicer 切片器。
- 支持通过透视表数据添加 Slicer 切片器。
- 支持移除 Slicer 切片器。
- 支持修改 Slicer 切片器。
- 支持获取 Slicer 切片器信息。
- 支持将 Excel 转换为 JSON 数据。
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
currentChangePercentage_Values = [0.23, 0.8, 1.1, 0.5, 0.35, 0.2]
increasedChangePercentage_Values = [0.45, 0.56, 0.9, 0.5, 0.58, 0.43]
decreasedChangePercentage_Values = [0.3, 0.2, 0.5, 0.3, 0.5, 0.23]
currentQuantity_Values = [1500, 3000, 5000, 4000, 500, 4000]
increasedQuantity_Values = [1000, 5000, 4500, 3900, 10000, 8900]
decreasedQuantity_Values = [1000, 2000, 3000, 3000, 300, 4000]
scenarios.Add("Current % of Change", worksheet.Range["F5:F10"], currentChangePercentage_Values)
scenarios.Add("Increased % of Change", worksheet.Range["F5:F10"], increasedChangePercentage_Values)
scenarios.Add("Decreased % of Change", worksheet.Range["F5:F10"], decreasedChangePercentage_Values)
scenarios.Add("Current Quantity", worksheet.Range["D5:D10"], currentQuantity_Values)
scenarios.Add("Increased Quantity", worksheet.Range["D5:D10"], increasedQuantity_Values)
scenarios.Add("Decreased Quantity", worksheet.Range["D5:D10"], decreasedQuantity_Values)
wb.SaveToFile(outputFile, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
currentChangePercentage_Values = [0.23, 0.8, 1.1, 0.5, 0.35, 0.2]
increasedChangePercentage_Values = [0.45, 0.56, 0.9, 0.5, 0.58, 0.43]
decreasedChangePercentage_Values = [0.3, 0.2, 0.5, 0.3, 0.5, 0.23]
currentQuantity_Values = [1500, 3000, 5000, 4000, 500, 4000]
increasedQuantity_Values = [1000, 5000, 4500, 3900, 10000, 8900]
decreasedQuantity_Values = [1000, 2000, 3000, 3000, 300, 4000]
scenarios.Add("Current % of Change", worksheet.Range["F5:F10"], currentChangePercentage_Values)
scenarios.Add("Increased % of Change", worksheet.Range["F5:F10"], increasedChangePercentage_Values)
scenarios.Add("Decreased % of Change", worksheet.Range["F5:F10"], decreasedChangePercentage_Values)
scenarios.Add("Current Quantity", worksheet.Range["D5:D10"], currentQuantity_Values)
scenarios.Add("Increased Quantity", worksheet.Range["D5:D10"], increasedQuantity_Values)
scenarios.Add("Decreased Quantity", worksheet.Range["D5:D10"], decreasedQuantity_Values)
worksheet.Scenarios.Summary(worksheet.Range["L7"])
wb.SaveToFile(outputFile, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
scenario1 = scenarios[0]
scenario2 = scenarios[1]
scenario1.SetVariableCells(worksheet.Range["A1:A5"], scenario2.Values)
sourceCell = worksheet.Range["B1:B5"]
scenario2.SetVariableCells(sourceCell, scenario2.Values)
scenario1.Show()
scenario2.Show()
self.get_content(scenario1, outputFile_TXT)
wb.SaveToFile(outputFile, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
scenarios.RemoveScenarioAt(0)
scenarios.RemoveScenarioByName("two")
content = ""
content += "Count:" + str(scenarios.Count) + "\n"
content += "ContainsScenario:" + str(scenarios.ContainsScenario("two")) + "\n"
content += "ContainsScenario:" + str(scenarios.ContainsScenario("one")) + "\n"
with open(outputFile, 'w') as f:
f.write(content)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
scenarios.RemoveScenarioAt(0)
scenarios.RemoveScenarioByName("two")
content = ""
content += "Count:" + str(scenarios.Count) + "\n"
content += "ContainsScenario:" + str(scenarios.ContainsScenario("two")) + "\n"
content += "ContainsScenario:" + str(scenarios.ContainsScenario("one")) + "\n"
with open(outputFile, 'w') as f:
f.write(content)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
slicers = worksheet.Slicers
table = worksheet.ListObjects.Create("Super Table", worksheet.Range["A1:C9"])
count = 3
for type in SlicerStyleType.__dict__.values():
if isinstance(type, SlicerStyleType):
count += 5
rangeStr = "E" + str(count)
index = slicers.Add(table, rangeStr, 0)
xlsSlicer = slicers[index]
xlsSlicer.Name = "slicers_" + str(count)
xlsSlicer.StyleType = type
wb.SaveToFile(outputFile_xlsx, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
pt = sheet.PivotTables[0]
slicers = worksheet.Slicers
index = slicers.Add(pt, "E12", 0)
xlsSlicer = slicers[index]
xlsSlicer.Name = "test_xlsSlicer"
xlsSlicer.Width = 100
xlsSlicer.Height = 120
xlsSlicer.StyleType = SlicerStyleType.SlicerStyleLight2
xlsSlicer.PositionLocked = True
slicerCache = xlsSlicer.SlicerCache
slicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithNoData
slicerCacheItems = xlsSlicer.SlicerCache.SlicerCacheItems
xlsSlicerCacheItem = slicerCacheItems[0]
xlsSlicerCacheItem.Selected = False
slicers_2 = worksheet.Slicers
r1 = pt.PivotFields["year"]
index_2 = slicers_2.Add(pt, "I12", r1)
xlsSlicer_2 = slicers[index_2]
xlsSlicer_2.RowHeight = 40
xlsSlicer_2.StyleType = SlicerStyleType.SlicerStyleLight3
xlsSlicer_2.PositionLocked = False
slicerCache_2 = xlsSlicer_2.SlicerCache
slicerCache_2.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithDataAtTop
slicerCacheItems_2 = xlsSlicer_2.SlicerCache.SlicerCacheItems
xlsSlicerCacheItem_2 = slicerCacheItems_2[1]
xlsSlicerCacheItem_2.Selected = False
pt.CalculateData()
wb.SaveToFile(outputFile_xlsx, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet_1 = wb.Worksheets[0]
slicers = worksheet_1.Slicers
slicers.RemoveAt(0)
slicer = worksheet_1.Slicers[1]
worksheet_1.Slicers.Remove(slicer)
worksheet_2 = wb.Worksheets[2]
worksheet_2.Slicers.Clear()
wb.SaveToFile(outputFile_xlsx, ExcelVersion.Version2013)
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
slicers = worksheet.Slicers
xlsSlicer = slicers[0]
xlsSlicer.StyleType = SlicerStyleType.SlicerStyleDark4
xlsSlicer.Caption = "Slicer"
xlsSlicer.PositionLocked = True
slicerCacheItems = xlsSlicer.SlicerCache.SlicerCacheItems
xlsSlicerCacheItem = slicerCacheItems[0]
xlsSlicerCacheItem.Selected = False
displayValue = xlsSlicerCacheItem.DisplayValue
slicerCache = xlsSlicer.SlicerCache
slicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithNoData
wb.SaveToFile(outputFile_xlsx, ExcelVersion.Version2013)
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
slicers = worksheet.Slicers
content = ""
content += "slicers.Count:" + str(slicers.Count) + "\n"
xlsSlicer = slicers[1]
content += "xlsSlicer.Name:" + xlsSlicer.Name + "\n"
content += "xlsSlicer.Caption:" + xlsSlicer.Caption + "\n"
content += "xlsSlicer.NumberOfColumns:" + str(xlsSlicer.NumberOfColumns) + "\n"
content += "xlsSlicer.ColumnWidth:" + str(xlsSlicer.ColumnWidth) + "\n"
content += "xlsSlicer.RowHeight:" + str(xlsSlicer.RowHeight) + "\n"
content += "xlsSlicer.ShowCaption:" + str(xlsSlicer.ShowCaption) + "\n"
content += "xlsSlicer.PositionLocked:" + str(xlsSlicer.PositionLocked) + "\n"
content += "xlsSlicer.Width:" + str(xlsSlicer.Width) + "\n"
content += "xlsSlicer.Height:" + str(xlsSlicer.Height) + "\n"
slicerCache = xlsSlicer.SlicerCache
content += "slicerCache.SourceName:" + slicerCache.SourceName + "\n"
content += "slicerCache.IsTabular:" + str(slicerCache.IsTabular) + "\n"
content += "slicerCache.Name:" + slicerCache.Name + "\n"
slicerCacheItems = slicerCache.SlicerCacheItems
xlsSlicerCacheItem = slicerCacheItems[1]
content += "xlsSlicerCacheItem.Selected:" + str(xlsSlicerCacheItem.Selected) + "\n"
with open(outputFile_T, 'w') as f:
f.write(content)
wb.Dispose()
workbook = Workbook()
workbook.LoadFromFile(inputFile)
workbook.SaveToFile(outputFile, FileFormat.Json)
workbook.Dispose()
Spire.Presentation for Python
新功能:
- 新增支持 License 环境变量配置,自动识别并加载以下三个环境变量:
SPIRE_OFFICE_LICENSE_KEY
SPIRE_PPT_LICENSE_KEY
SPIRE_LICENSE_KEY
优化:
- 优化了多个接口的处理逻辑,进一步消除了潜在的体验隐患。
问题修复:
- 修复了加载PPTX文档时,程序抛出“Microsoft PowerPoint 2007 file is corrupt.”异常的问题。
- 修复了加载PPTX文档时,程序抛出“Arg_NullReferenceException”异常的问题。
Spire.PDF for Python
新功能:
- 添加 AutoFontSize 属性,支持自动调整签名域内文本内容的大小。
# 初始化 PDF 文档对象
doc = PdfDocument()
# 加载需要签名的 PDF 文件
doc.LoadFromFile(inputFile)
# 指定 PFX 证书文件的密码
pfxPassword = "e-iceblue"
# 获取文档的第一页
page = doc.Pages.get_Item(0)
# 使用证书文件创建普通签名制作器
signatureMaker = PdfOrdinarySignatureMaker(doc, inputFile_pfx, pfxPassword)
# 设置签名验证层(False 表示显示有效性符号)
signatureMaker.SetAcro6Layers(False)
# 获取签名对象并配置签署人的基本信息
signature = signatureMaker.Signature
signature.Name = "Gary" # 签署人姓名
signature.ContactInfo = "028-81705109" # 联系方式
signature.Location = "Chengdu" # 签署地点
signature.Reason = "The certificate of this document" # 签署原因
# 创建自定义签名外观对象
appearance = PdfSignatureAppearance(signature)
appearance.NameLabel = "Signer: " # 姓名标签
appearance.ContactInfoLabel = "ContactInfo: " # 联系方式标签
appearance.LocationLabel = "Location: " # 地点标签
appearance.ReasonLabel = "Reaseon: " # 原因标签(保留原文拼写)
appearance.SignatureImage = PdfImage.FromFile(inputFile_image) # 加载签名图片
appearance.GraphicMode = GraphicMode.SignImageAndSignDetail # 同时显示签名图片和详细信息
signature.DocumentPermissions = PdfCertificationFlags.ForbidChanges # 禁止更改文档
appearance.SignImageLayout = SignImageLayout.Stretch # 签名图片拉伸布局
appearance.AutoFontSize = True # 启用自动调整字体大小
# 在页面指定位置生成并应用签名(参数顺序:签名字段名、页对象、X坐标、Y坐标、宽度、高度、外观对象)
signatureMaker.MakeSignature("signName", page, 54.0, page.Size.Height - 300.0, 40.0, 40.0, appearance)
# 保存已签名的 PDF 文档
doc.SaveToFile(outputFile)
# 关闭文档并释放资源
doc.Close()
问题修复:
- 修复了替换文本后字体显示不正确的问题。







