使用pywin32保护Excel工作表时无法设置任何属性

问题描述 投票:0回答:1

我正在一个项目中使用 pywin32,以使用 python 自动化一些 excel 文件。

在Excel文件中,我想保护所有包含公式的单元格。
所以,我首先解锁所有单元格,然后只锁定那些有公式的单元格。
当我使用密码保护工作表时,我还传递了所有相关的保护属性,例如;
允许格式化单元格,
允许格式化列,
允许格式化行,
允许插入列,
允许插入行,
允许排序和
允许过滤
并将它们设置为 True。但是,如果我在保护工作表后检查属性是什么,它们将返回 False。

当我使用 Excel 打开文件时,工作表受到保护,我可以编辑解锁单元格的内容,但无法格式化、筛选、插入列或行或执行任何其他操作。

相关信息

  • Python版本:3.11.9
  • pywin32版本:306
  • Excel 版本:Microsoft® Excel® for Microsoft 365 MSO(版本 2402 内部版本 16.0.17328.20550)64 位
  • Windows:Windows 11 企业版
  • 版本23H2
  • 于2023年10月18日安装
  • 操作系统版本 22631.4317
  • 体验 Windows 功能体验包 1000.22700.1041.0

下面是用于重现性的Python代码

import win32com.client


excel_app = win32com.client.DispatchEx("Excel.Application")
excel_app.Visible = False
workbook = excel_app.Workbooks.Open("path_to_file.xlsx")

sheet = workbook.Sheets("Sheet1")

all_cells = sheet.Cells
merge_cells = sheet.Cells(1, 1).MergeArea
edited_cell = merge_cells.Cells(1, 1)
value = edited_cell.Formula if edited_cell.HasFormula else edited_cell.Value

edited_cell.Formula = "=1+1"

formula_cells = all_cells.SpecialCells(Type=-4123)  # -4213 represent xlCellTypeFormulas

all_cells.Locked = False
formula_cells.Locked = True

if isinstance(value, str) and value.startswith("="):
    edited_cell.Formula = value
else:
    edited_cell.Value = value
    merge_cells.Locked = False


sheet.Protect(
    Password="random_password",
    Contents=True,
    UserInterfaceOnly=True,
    AllowFormattingCells=True,
    AllowFormattingColumns=True,
    AllowFormattingRows=True,
    AllowInsertingColumns=True,
    AllowInsertingRows=True,
    AllowSorting=True,
    AllowFiltering=True,
)

print("AllowFormattingCells: ", sheet.Protection.AllowFormattingCells)
print("AllowFormattingColumns: ", sheet.Protection.AllowFormattingColumns)
print("AllowFormattingRows: ", sheet.Protection.AllowFormattingRows)
print("AllowInsertingColumns: ", sheet.Protection.AllowInsertingColumns)
print("AllowInsertingRows: ", sheet.Protection.AllowInsertingRows)
print("AllowSorting: ", sheet.Protection.AllowSorting)
print("AllowFiltering: ", sheet.Protection.AllowFiltering)

workbook.Save()

excel_app.Quit()

当我在使用 Excel 时手动设置保护时,保护按预期工作。但是,当我使用 pywin32 设置它时,保护正在工作,但未设置保护属性,因此我无法添加行、使用过滤器等。

我已经尝试了“内容”和“UserInterfaceOnly”的所有组合,看看是否会导致它发生变化。

python excel pywin32
1个回答
0
投票

我最初在装有 Excel 2013 的 Windows 10 PC 上进行了测试,正如所述,您的代码可以正常工作。
然后我尝试了一台装有 Excel 2021 的 Windows 10 电脑,它似乎表现出与您相同的问题,保护设置为 True 后仍为 False。
尝试调试并专门将保护值更新为 True 失败并返回错误。

然后,我尝试在同一台 Excel 2021 PC 上使用 Xlwings(也使用 Excel 应用程序,类似于 win32com)应用相同的保护措施,效果很好,所以假设使用没有问题,它可能会为您的设置带来帮助Xlwings.

import xlwings as xw
from xlwings import constants


in_excelfile = 'unprotected.xlsx'
out_excelfile = 'protected.xlsx'

with xw.App(visible=True) as xl:
    wb = xw.Book(path_to_excel)
    ws = wb.sheets["Sheet1"]

    # Get range of used cells, this is the range of cells in the sheet with values  
    sheet_range = ws.used_range
    # Set all cells in the sheet_range Locked status to False
    ws.range(sheet_range).api.Locked = False
    # Select all cells with formulas in the sheet_range and set Locked to True
    ws.range(sheet_range).api.SpecialCells(constants.CellType.xlCellTypeFormulas, 23).Locked = True

    # Set the protection states
    ws.api.Protect(
        Password='random_password',
        Contents=True,
        UserInterfaceOnly=True,
        AllowFormattingCells=True,
        AllowFormattingColumns=True,
        AllowFormattingRows=True,
        AllowInsertingColumns=True,
        AllowInsertingRows=True,
        AllowSorting=True,
        AllowFiltering=True,
    )

    # Print the Status of the Protections 
    print(f"AllowFormattingCells: {ws.api.Protection.AllowFormattingCells}")
    print(f"AllowFormattingColumns: {ws.api.Protection.AllowFormattingColumns}")
    print(f"AllowFormattingRows: {ws.api.Protection.AllowFormattingRows}")
    print(f"AllowInsertingColumns: {ws.api.Protection.AllowInsertingColumns}")
    print(f"AllowInsertingRows: {ws.api.Protection.AllowInsertingRows}")
    print(f"AllowSorting: {ws.api.Protection.AllowSorting}")
    print(f"AllowFiltering: {ws.api.Protection.AllowFiltering}")

    # Save file
    wb.save(out_excelfile)

因此,在这种情况下,所有保护都返回状态“True”,并且再次能够像以前一样格式化单元格并插入行和列。公式单元格被锁定,其他单元格可以编辑。

© www.soinside.com 2019 - 2024. All rights reserved.