尝试替换 excel 文件中的部分链接时数据损坏

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

我正在尝试编写一个代码,它将递归地遍历本地驱动器上的文件夹,查找 *.xlsx 和 *.xls 文件,扫描链接并用输入文本替换部分链接...

我是 Python 的新手......这就像我的第 2 天...... 请帮助

我试过这段代码,但似乎我做错了什么...... 输出文件损坏意味着 excel 无法打开它。


import os
import openpyxl

FileDIR = input( "Folder: " )
ReplaceMe = input( "Replace: " )
ReplaceWith = input( "With: " )

FileCounter=0
for root, dirs, files in os.walk(FileDIR):
    for file in files:
        
        XLSXFileDIR = os.path.join(root, file)
        
        if file.lower().endswith(('.xlsx', '.xls')):
            
            FileCounter = FileCounter+1
            
            wb=openpyxl.load_workbook(XLSXFileDIR)
            
            links=wb._external_links
            
            LinkCounter=0
            for index, item in enumerate(links):
                Mystr =wb._external_links[index].file_link.Target
                Mystr=Mystr.replace("file:///","")
                Mystr=Mystr.replace("%20"," ")
                
                Mystr=Mystr.replace(ReplaceMe,ReplaceWith)
                
                LinkCounter=LinkCounter+1
                print("Link to: "+Mystr+" Found in: "+file)
            
            wb.save(os.path.join(root, "NEW_"+file))
            
print (str(FileCounter)+" Excel Files scaned /"+str(LinkCounter)+" Links found")


python python-3.x excel openpyxl
1个回答
0
投票

您是否尝试修改单元格中的超链接并将更改保存在新工作簿中?
如果是这样,我不明白为什么你会得到一个损坏的文件。该代码对任何文件都没有任何作用,您打开一个文件,然后使用具有前缀“NEW_”的相同名称保存它。代码中的任何内容都不会更改工作簿/工作表中的任何内容,因此我看不到任何内容是如何损坏的。

关于代码的其他评论

  1. Openpyxl 只支持 xlsx 文件。您不能以任何方式打开或修改

    xls
    文件,尝试打开任何文件只会返回
    not a zip file
    错误。

  2. 计数器的递增通常用

    +=
    完成,所以 FileCounter 递增应该是;

    文件计数器 += 1

  3. wb._external_links
    会返回并清空列表

  4. links
    循环中有两个计数器,LinkCounter 和 index,它们做同样的事情。您只需在循环中使用
    index
    并与 LinkCounter 求和,因为每个文件都会针对所有链接计数进行处理。

  5. 我认为超链接永远不会包含文本

    file:///
    。这是 Excel 内部的文件指示器,因此链接永远不会包含它。

以下代码示例将执行您的代码似乎正在尝试的操作。
它会修改您的代码并包含上面列出的注释。

  1. 在您的目录中创建一个“xlsx”文件列表以循环访问。
  2. 将 FileCounter 作为从“1”开始的枚举器移动
  3. 迭代文件循环并打开活动或默认工作表
    ws = wb.active
    。这可能不是必需的工作表,或者可能有超过 1 个工作表要处理。如果是这样,可能需要指定所需的工作表,或者还可能需要循环遍历工作簿工作表。
  4. 迭代行和列范围,默认情况下这是工作表中使用的范围。检查范围内的每个单元格是否有超链接,如果找到超链接,则应用字符串替换。如果没有找到,则跳过该单元格。 LinkCounter 增量包含在循环中。
  5. 检查完所有单元格后,文件保存为
    NEW_<file name>
  6. 下一个文件如上处理
  7. 文件和链接计数使用 f 字符串打印

如果您打算修改链接并另存为新工作簿;我在代码示例中包含了该行

cell_hyperlink.target = Mystr

此行会将链接文本更新为保存文本替换的变量

Mystr
的链接文本,因此在保存工作簿时将应用这些更改。

代码示例

import os
import openpyxl


FileDIR = input("Folder: ")
ReplaceMe = input("Replace: ")
ReplaceWith = input("With: ")

FileCounter = 0
LinkCounter = 0

### Create a list of files in the entered directory that end with '.xlsx'
files = [f for f in os.listdir(FileDIR) if f.endswith('.xlsx')]

### Loop the files list to process each file. Include FileCounter starting at value 1    
for FileCounter, file in enumerate(files,1):

    XLSXFileDIR = os.path.join(FileDIR, file)

    ### Open the file in Openpyxl    
    wb = openpyxl.load_workbook(XLSXFileDIR)
    ### Open the default worksheet
    ws = wb.active

    ### Iterate rows and cells in the row. index is initiated with value 1    
    for row in ws.iter_rows():
        for cell in row:
            ### Check if the cell has a hyperlink
            if cell.hyperlink is not None:
                ### Increment LinkCounter
                LinkCounter += 1

                ### Assign hyperlink att to cell_hyperlink
                cell_hyperlink = cell.hyperlink
                ### Assign hyperlink link text to Mystr
                Mystr = cell_hyperlink.target

                ### This line not expected to do anything
                # Mystr = Mystr.replace("file:///", "")

                ### Other text replacements 
                Mystr = Mystr.replace("%20", " ")
                Mystr = Mystr.replace(ReplaceMe, ReplaceWith)
                
                ### update the hyperlink text with the new path after string replacements
                cell_hyperlink.target = Mystr

                print("Link to: " + Mystr + " Found in: " + file)
    
    ### Save workbook to new name 
    wb.save(os.path.join(FileDIR, "NEW_" + file))

### Print FileCounter and LinkCounter results using f string
print(f'{FileCounter} Excel Files scaned {LinkCounter} Links found')
© www.soinside.com 2019 - 2024. All rights reserved.