按xls标签替换docx及xls内容

news2024/11/23 19:49:35

WPSoffice环境下,需要批量替换doc文档及xls表格某些内容,在windows下,可以用VBA宏实现,先建一个标签表格,然后按标签批量替换。但在Linux下,WPS表格宏不能跨文档操作WPS文字,于是想用python实现。

1、标签文件与模板文件格式:

标签文件A列为标签名,B列为值。

模板文件关键词用#包围,如下:

2、基本功能

读入标签内容,然后打开模板文件,替换关键词为标签值,保存到新文件。

用到的python库:xlrd、xlutils、tkinter。读入的标签及文件列表使用Treeview展示,并提供修改、增加项、删除项功能。

3、几个重要代码片段

3.1 读xls内容

        # 读入标签表
        # 打开一个 Excel 文件
        workbook = xlrd.open_workbook(fname)
        # 通过索引获取第一个工作表
        sheet = workbook.sheet_by_index(0)
        da = []
        # 遍历所有行和列输出
        for i in range(sheet.nrows):
            # 键值分布在1、2列
            key = str(sheet.cell_value(i, 0)).replace(' ', '')    # 删除空格
            val = sheet.cell_value(i, 1)
            date_format = sheet.cell_type(i, 1)
            # 日期类型
            if date_format == xlrd.XL_CELL_DATE:
                date_tuple = xlrd.xldate_as_tuple(val, workbook.datemode)
                val = '' + str(date_tuple[0]) + "年" + str(date_tuple[1]) + "月" + str(date_tuple[2]) + "日"
            # 文本类型
            if date_format == xlrd.XL_CELL_TEXT:
                val = '' + sheet.cell_value(i, 1)
            if str(key) != '':
                da.append((key, val))
        # print(da)
        workbook.release_resources()
        del workbook

3.2 替换docx文档关键词

    def procdocx(self, fname, lbitems, foutname):
        document = Document(fname)    # 打开文档

        for paragraph in document.paragraphs:
            runs = paragraph.runs  # 得到所有run
            for i, run in enumerate(runs):
                key = run.text
                # 当前run不包含key值
                if key.count('#') == 0:
                    continue
                counter = i  # 记录起始位置
                if key.count('#') == 1:  # 如先导符与key值分在多个run中
                    while counter < len(runs):  # 将先导符与后续run组成key后再查找
                        counter = counter + 1
                        if counter >= len(runs):
                            break
                        key += runs[counter].text
                        tmp = runs[counter].text
                        runs[counter].clear()    # 清空当前runs,本算法会改变文档内容格式
                        if tmp.count('#') > 0:   # 注:如果有多个连续#,且第二个key分在多个run中,会有可能出现替换错误
                            break
                # 开始替换
                for item in lbitems:
                    key1 = '#' + self.labeltree.item(item)['values'][0].replace(' ', '') + '#'
                    if key.find(key1) >= 0:
                        # for j in range(i, counter + 1):
                        #    runs[j].clear()
                        key = key.replace(key1, self.labeltree.item(item)['values'][1])
                runs[i].text = key
        # 另存到输出文件夹
        document.save(foutname)

3.3 替换xls表格关键词

    def procxls(self, fname, lbitems, foutname):
        modxls = xlrd.open_workbook(fname, formatting_info=True)
        # 将操作文件对象拷贝,变成可写
        newxls = copy(modxls)
        # 获取所有sheet页及数量
        sheets = modxls.sheet_names()
        for shn in range(len(sheets)):
            # 通过索引获取第shn个工作表
            modsheet = modxls.sheet_by_index(shn)
            newsheet = newxls.get_sheet(shn)

            # 遍历mod所有行和列输出
            for i in range(modsheet.nrows):
                for j in range(modsheet.ncols):
                    val = modsheet.cell_value(i, j)
                    val_format = modsheet.cell_type(i, j)
                    if val_format != xlrd.XL_CELL_TEXT:
                        continue
                    # 开始替换
                    for item in lbitems:
                        key1 = '#' + self.labeltree.item(item)['values'][0].replace(' ', '') + '#'
                        if val.find(key1) >= 0:
                            newval = val.replace(key1, self.labeltree.item(item)['values'][1])
                            newsheet.write(i, j, newval)
        newxls.save(foutname)

3.4 Treeview代码

1) 创建一个treeview列表

        # 创建 self.labeltree 并添加到 self.mainframe 中
        columns1 = ("label", "value")
        self.labeltree = ttk.Treeview(frame51, show="headings", columns=columns1)
        self.labeltree.column('label', width=100, anchor='w')
        self.labeltree.heading('label', text="标签名")
        self.labeltree.column('value', width=300, anchor='w')
        self.labeltree.heading('value', text="标签值")
        self.labelscrollx = ttk.Scrollbar(frame51, orient="horizontal", command=self.labeltree.xview)
        self.labelscrolly = ttk.Scrollbar(frame51, orient="vertical", command=self.labeltree.yview)
        self.labeltree.configure(xscrollcommand=self.labelscrollx.set)
        self.labeltree.configure(yscrollcommand=self.labelscrolly.set)
        self.labelscrollx.pack(side="bottom", fill="x")
        self.labelscrolly.pack(side="right", fill="y")
        self.labeltree.pack(expand=1, fill='both', padx='1', pady='1')

2) 双击treeview编辑

    # 双击标签库列表
    def set_lbcell_value2(self, event):
        # 获取选中的项目
        col = self.labeltree.identify_column(event.x)  # 列
        row = self.labeltree.identify_row(event.y)  # 行
        if col == '' or row == '':
            return
        selected_item = self.labeltree.selection()[0]
        cn = int(str(col).replace('#', ''))
        rn = int(str(row).replace('I', ''))
        x, y, w, h = self.labeltree.bbox(selected_item, col)
        txt = self.labeltree.item(selected_item, 'values')[cn-1]
        edstr = StringVar()
        edstr.set(txt)
        entryedit = ttk.Entry(self.labeltree, width=w//8, textvariable=edstr)
        entryedit.place(x=x, y=y)

        def saveedit(even):
            self.labeltree.set(selected_item, column=col, value=edstr.get())
            entryedit.destroy()

        entryedit.bind("<FocusOut>", saveedit)
        # 按下时触发
        entryedit.bind('<Return>', saveedit)  # 不是Enter而是Return

3) 右击treeview,弹出操作菜单

    # 右击标签库
    def set_lbcel_popup(self, event):
        # 创建右键菜单
        self.right_click_menu = Menu(self.labeltree, tearoff=False)
        self.right_click_menu.add_command(label="增加", command=lambda: self.on_menu_click_add(event))
        if self.labeltree.selection():
            self.right_click_menu.add_command(label="删除", command=lambda: self.on_menu_click_del(event))
        self.right_click_menu.post(event.x_root, event.y_root)

    # 新增标签
    def on_menu_click_add(self, event):
        self.labeltree.insert('', 'end', values=('新标签', '值'))
        self.labeltree.update()

    # 删除标签
    def on_menu_click_del(self, event):
        if self.labeltree.selection():
            self.labeltree.delete(self.labeltree.selection())

4、几个不足之处:

1)python-docx库只能操作docx文件,对doc文档支持不好。

2)对模板文档中标签格式有一定要求,但基本功能已实现。

5、源代码已上传,链接:https://download.csdn.net/download/zhoury/89612390

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1983208.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工程架构简析

文内项目 Github&#xff1a;XIAOJUSURVEY 架构 架构的设计最终是为了场景可以快速扩展&#xff0c;基于工程底座&#xff0c;使用者能够专注于业务领域的深入。 B端&#xff1a;面向问卷管理者&#xff0c;专注于问卷管理、问卷投放和数据分析三大核心能力的建设。&#xff0…

vue3实现商品图片放大镜效果(芋道源码yudao-cloud 二开笔记)

今天开发一个防某商城的商品图片放大镜&#xff0c;鼠标移动到图片位置时&#xff0c;右侧出现一个已放大的图片效果。 示例如下&#xff1a; 下图的图片的放大效果和小图的切换封装成了组件PicShow.vue&#xff0c;可根据需求自行修改&#xff0c;如下&#xff1a; 第一步&…

鸿蒙应用服务开发【钱包服务(ArkTS)】

介绍 基于Stage模型&#xff0c;提供钱包交通卡和Pass卡的开卡、预览卡、查询卡信息、更新卡片信息、删除卡片、初始化钱包环境等功能。 效果预览 具体实现 交通卡 在hms.core.payment.walletTransitCard中定义了钱包交通卡接口API&#xff0c;示例接口如下&#xff1a; /*…

【漏洞复现】用友NC Cloud系统queryPsnInfo接口SQL注入

文章目录 0x00 漏洞描述影响范围 0x01 测绘工具0x02 漏洞复现0x03 Nuclei检测脚本0x04 修复建议0x05 免责声明 0x00 漏洞描述 用友NC Cloud存是一款大型企业数字化平台。 在受影响的版本中&#xff0c;攻击者可以通过未授权访问 /ncchr/pm/obj/queryPsnInfo 接口&#xff0c;利…

综合安防管理平台LntonCVS视频监控汇聚平台视频数据智能化与资源共享方案

随着全球城市化进程的加快&#xff0c;智慧城市概念日益受到重视。在这一趋势下&#xff0c;LntonCVS视频汇聚平台作为新型智慧城市的重要智能基础设施之一&#xff0c;扮演着关键角色。该平台整合、接入和管理城市中各类视频资源&#xff0c;涵盖公共安全视频、交通监控、城市…

【五大海内外高校支持】2024年数字经济与计算机科学国际学术会议(DECS2024)

大会官网&#xff1a;www.icdecs.net 大会时间&#xff1a;2024年9月20-22日 大会地点&#xff1a;中国-厦门 截稿日期&#xff1a;详情见官网 支持单位 马来西亚理工大学 北京科技大学经济管理学院 南京信息工程大学 马来西亚敦胡先翁大学 大会嘉宾 大会主席 罗航…

opencascade AIS_ViewController源码学习 视图控制、包含鼠标事件等

opencascade AIS_ViewController 前言 用于在GUI和渲染线程之间处理视图器事件的辅助结构。 该类实现了以下功能&#xff1a; 缓存存储用户输入状态&#xff08;鼠标、触摸和键盘&#xff09;。 将鼠标/多点触控输入映射到视图相机操作&#xff08;平移、旋转、缩放&#xff0…

Mybatis(Day 18)

数据持久化是将内存中的数据模型转换为存储模型&#xff0c;以及将存储模型转换为内存中数据模型的统称。MyBatis 支持定制化 SQL、存储过程以及高级映射&#xff0c;可以在实体类和 SQL 语句之间建立映射关系&#xff0c;是一种半自动化的 ORM 实现。ORM&#xff08;Object Re…

系统运维——PXE自动安装系统

摘要 PXE&#xff08;Preboot Execution Environment&#xff0c;预启动执行环境&#xff09;是一种允许计算机通过网络启动操作系统而无需本地存储设备的技术。本文详细介绍了 PXE 的定义、架构、原理、应用场景及常见命令体系。以 RedHat7 为例&#xff0c;展示如何配置和使…

Tooltip 文字提示

在偶然维护前端开发时&#xff0c;遇到页面列表中某个字段内容太长&#xff0c;且该字段使用了组件显示&#xff0c;导致不能使用纯文本得那个省略号代替显示得css样式效果&#xff0c;如下 所以只能另辟溪路了&#xff0c; 1、最开始想到是使用横向滚动得效果来实现&#xff…

【Vue3】Pinia存储及读取数据

【Vue3】Pinia存储及读取数据 背景简介开发环境开发步骤及源码 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日…

如何用OceanBase与DataWorks,打造一站式的数据集成、开发和数据服务

导语&#xff1a;在OceanBase 2024年开发者大会的技术生态论坛上&#xff0c;阿里云DataWorks团队的高级技术专家罗海伟&#xff0c;详细阐述了一站式大数据开发治理平台DataWorks的能力&#xff0c;并对于如何基于OceanBase和Dataworks构建一站式数据集成、开发以及数据服务进…

解锁模数学习新境界:电路仿真软件,你的数字与模拟世界桥梁大师!

在这个科技日新月异的时代&#xff0c;模数转换&#xff08;A/D与D/A&#xff09;不仅是电子工程师的必修课&#xff0c;也是众多科技爱好者探索数字与模拟世界奥秘的钥匙。而今&#xff0c;一款强大的电路仿真软件&#xff0c;正悄然成为连接这两大领域的魔法棒&#xff0c;让…

Animate软件基础:各种类型文件使用说明

FlashASer&#xff1a;AdobeAnimate2021软件零基础入门教程https://zhuanlan.zhihu.com/p/633230084 FlashASer&#xff1a;实用的各种Adobe Animate软件教程https://zhuanlan.zhihu.com/p/675680471 FlashASer&#xff1a;Animate教程及作品源文件https://zhuanlan.zhihu.co…

ps绘制动图

ps绘制动图教程&#xff08;简易版&#xff09;-直播gif动态效果图 第一步 打开ps绘制几个简单的长方形 第二步 将图层转化为智能图层 第三部 在窗口找到时间轴创建时间轴 第五步 通过变换来鼠标控制图像的变化并打下结束点 第六部 通过图像中的图像大小控制gif的大小 第七部 …

低代码: 系统开发准备之确定一般开发流程,需求分析,复杂度分析,标准开发流程

概述 低代码系统开发之前&#xff0c;我们首先要进行一些准备我们首先知道我们软件开发的一般流程同时&#xff0c;我们还要知道&#xff0c;我们整个系统平台的需求如何之后&#xff0c;我们要基于需求进行设计&#xff0c;包含UI设计与系统架构设计 一般开发流程 系统开发…

2024年【北京市安全员-B证】考试题库及北京市安全员-B证考试技巧

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 北京市安全员-B证考试题库根据新北京市安全员-B证考试大纲要求&#xff0c;安全生产模拟考试一点通将北京市安全员-B证模拟考试试题进行汇编&#xff0c;组成一套北京市安全员-B证全真模拟考试试题&#xff0c;学员可…

拉削基础知识——拉床的类型及特点

拉床是所有机械加工工具中最简单的一种&#xff0c;由拉削工具、夹具、驱动装置和支撑架组成。拉削加工可获得较高的尺寸精度和较小的表面粗糙度&#xff0c;生产率较高&#xff0c;适用于大批量生产。拉床按其结构主要分为卧式和立式。应用领域和功能可分为液压拉床、自动拉床…

【香菇带你学Mysql】Mysql数据库主备搭建【建议收藏】

文章目录 1. 概述1.1 为什么要搭建主备架构数据库&#xff1f;1.2 常见的Mysql数据库主备架构 2. Mysql 数据库主备搭建原理3. Mysql数据库主备搭建实操3.1 环境准备3.2 主库操作3.3 从库操作3.4 主从同步验证 4. 总结5. 参考文档 大家可能听过一个段子&#xff0c;当电脑遇到问…

java 关键字

Java的关键字是语言中保留的标识符&#xff0c;它们具有特定的含义和用途&#xff0c;并且不能用作变量名、方法名或类名等。Java 17&#xff08;最新的LTS版本之一&#xff09;中有53个关键字。 下面是每个关键字的含义及其实例 1. 控制结构关键字 这些关键字用于控制程序流…