V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
junniuLi
V2EX  ›  Python

Python 在 execl 中间插入数据

  •  
  •   junniuLi · 2020-08-26 15:25:46 +08:00 · 3327 次点击
    这是一个创建于 1550 天前的主题,其中的信息可能已经有所发展或是发生改变。
    python 怎样才能在 excel 中间插入数据,并且格式保持不变?比如就是一个 execl 模板,模板前几行是一些标注,最后几行也有标注,标注都渲染了格式就是有的合并了,有的标注了颜色等。中间是空白行,用来插入数据,我现在的问题是在中间插入多行数据,但是数据一多会覆盖掉最后几行标注的格式。如何才能做到只在中间插入而保证前后格式都不变?
    26 条回复    2020-08-27 19:50:52 +08:00
    fhsan
        1
    fhsan  
       2020-08-26 15:29:41 +08:00
    我反正不会用 python 搞 excel 格式
    junniuLi
        2
    junniuLi  
    OP
       2020-08-26 15:34:48 +08:00
    @fhsan 我不想每次都写一遍格式加到后面,所以想找个取巧的方法,但是找不到
    BBrother
        3
    BBrother  
       2020-08-26 16:03:25 +08:00
    junniuLi
        4
    junniuLi  
    OP
       2020-08-26 16:23:15 +08:00
    @BBrother 好像不是,我的想法就是想在中间插数据,类似在 excel 中增加一行,下面的行自动下移,这样不会影响最后的格式。我用 openpyxl 的 inser_rows ()插入空行,虽然可以使标注的那几行向下移动,但是标注的格式还是会被覆盖,而且在原来的标注的位置,新增的空行会被原来的格式影响,例如原来合并的列,新增的空行也会合并。 就很麻烦~
    xiaolinjia
        5
    xiaolinjia  
       2020-08-26 16:30:03 +08:00
    我用 win32com 弄过类似的。win32com 有所有 execl 的这些原生 api 。就是文档不好找。
    BBrother
        6
    BBrother  
       2020-08-26 16:42:58 +08:00
    @junniuLi 别用 python 了,直接录个宏吧
    jerfoxu
        7
    jerfoxu  
       2020-08-26 16:48:20 +08:00
    能不能把最后的标注每次录完数据复制上去呢?
    Vegetable
        8
    Vegetable  
       2020-08-26 16:53:39 +08:00
    你直接 insert_row 会覆盖格式吗?这和我认知不一样,我记得样式都是和单元格绑定的,你是直接在现有单元格上写入吗?
    JCZ2MkKb5S8ZX9pq
        9
    JCZ2MkKb5S8ZX9pq  
       2020-08-26 16:54:30 +08:00
    我试过好几种,都不理想。
    我的情况是 excel 带了不少特殊格式,条件格式,等等。主要是用来给客户做一个 GUI 的展示。

    目前采取的是两种方式。
    一种是直接 python 输出类似 csv 的格式,公式列就是公式的字符串,然后把整个 csv 直接在 python 复制到剪切板后,手动黏贴进 excel 。
    另一种比较大型的,带图片等等的。就是直接用 python 写一个新的 excel (用 xlsxwriter ),但是基本不带格式,单独保存。然后手动把新的 excel 数据黏贴进模板 excel 里。

    ----------

    直接写 excel 带格式的,尝试过直接用模块读取模板 excel 文件,然后往模板里写入数据,但实际会有许多问题。跟那个模块的开发者交流过,对方意思他用的是一个第三方标准,好像是 open 啥的 table/excel 大概这类名字,里面支持的特性有限,有些比较冷门的 excel 特性就没考虑去支持。

    ----------

    VBA 嘛弄过点,但没找到文档,感觉写 /调试起来不顺手,就没深入。
    junniuLi
        10
    junniuLi  
    OP
       2020-08-26 16:54:31 +08:00
    @jerfoxu 找不到简便的方法的话,也只能这样了~
    JCZ2MkKb5S8ZX9pq
        11
    JCZ2MkKb5S8ZX9pq  
       2020-08-26 17:05:56 +08:00
    [openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm files — openpyxl 3.0.5 documentation]( https://openpyxl.readthedocs.io/en/stable/)

    以前试过的一个工具 xlrd 好像更新了,有空 LZ 可以试试,我蹲一个反馈。
    xlutils.copy 我也用过,当时也是不行的,不知道有没有更新。
    junniuLi
        12
    junniuLi  
    OP
       2020-08-26 17:07:08 +08:00
    @Vegetable 可能我没说清楚,我的意思是比如原来标注内容的在第五行,第五行格式为 1-6 列合并后居中,用 insert_rows () 插入一行后,现在的第五行为新插入的空白行,格式没有改变还是合并后居中。但是我是想要的效果是插入的空白行保持默认格式 ,就类似于在 excel 中的空白行点击插入,生成一个默认格式的空白行,而不是生成一个合并后的空白行~
    junniuLi
        13
    junniuLi  
    OP
       2020-08-26 17:07:42 +08:00
    @JCZ2MkKb5S8ZX9pq 非常感谢~
    junniuLi
        14
    junniuLi  
    OP
       2020-08-26 17:15:01 +08:00
    @JCZ2MkKb5S8ZX9pq xlutils.copy 我也试过,也不行
    pcbl
        15
    pcbl  
       2020-08-26 17:19:15 +08:00 via iPhone
    我之前是把 excel 另存为 html 作为模板,python 修改 html 后,改文件后缀名为 xls 。。。
    Vegetable
        16
    Vegetable  
       2020-08-26 17:19:41 +08:00
    @junniuLi #11 试了一下,合并单元格这个的确不属于单元格的样式,会被新插入的数据搞乱,帮不上忙了
    JCZ2MkKb5S8ZX9pq
        17
    JCZ2MkKb5S8ZX9pq  
       2020-08-26 17:23:58 +08:00
    @junniuLi 你有空试试吧,我蹲一个。

    我们广告行业,客户间通行的文件就是 excel,客户大都有二次编辑的需求,很无奈。
    我比较常用的匹配不到的部分是条件格式 /数据条 /色阶,这类偏视觉呈现的。但表格结构还是比较严格的数据表,类似 sql/access 这种的。

    像你合并单元格这种玩意儿我倒是没试过,但感觉支持度可能不会很好。因为这是更加不像数据表的用法。如果客户不介意,可以考虑直接网页。

    另外我觉得你的这个需求(我没有很明白),也许不用 python 。
    我不知道你对 excel 的熟悉程度怎么样,我解释一个比较基础的关于 [表格] 的部分。

    -----

    excel 默认的其实不是表格,我记得好像是叫表单(基本不用,忘了)。
    你随便建一点数据,5x5 这样,然后全选,到顶部 [插入] 选项卡,点表格。经过这步转换,这里得到的就是表格。
    然后你选中表格中的任何一个单元格,顶部就会有 [设计] 选项卡,可以选视觉样式和汇总行这类的东西。

    重要的有几个地方:
    1. 这样的表格里,公式的引用写法会变成列名,非常方便。
    2. 直接默认待了筛选工具(可以关闭)
    3. ctrl+shift+加号,添加行,会自动扩展表格大小。而你的需求,如果在这里黏贴的话,其实底部的内容是会自动下移的。(当然如果不是表格,也可以选择下移,但表格方便一点。)
    4. 从命名选择器里,可以对表格命名(跨表格引用会用到)。

    反正表格特性挺多的,也蛮多人不知道的。但熟悉之后,一般就只会用到这种比较严谨的数据表格。在熟悉这些特性之后,你可以考虑根据需求,调整一下表格的结构设计。
    sniperhgy
        18
    sniperhgy  
       2020-08-26 17:24:45 +08:00
    @junniuLi 建议还是用 VBA 来完成这类 Excel 操作,比较方便,毕竟 python 是胶水,太定制化的东西,比不过原生自带的。如果觉得 VBA 的学习成本大,就干脆录一个宏,然后改改就能用了。
    junniuLi
        19
    junniuLi  
    OP
       2020-08-26 17:27:45 +08:00 via Android
    @pcbl 没有想到这个方法, 请教下,这样是怎么弄的?
    junniuLi
        20
    junniuLi  
    OP
       2020-08-26 17:33:28 +08:00 via Android
    pcbl
        21
    pcbl  
       2020-08-26 18:01:04 +08:00 via iPhone
    @junniuLi 把 excel 模板另存为 html,python 去操作 html 比较容易,然后把生成的文件改个后缀名变成 xls 文件。
    缺点是打开的时候 excel 会有一个确认框
    xiaolinjia
        22
    xiaolinjia  
       2020-08-26 18:07:45 +08:00   ❤️ 1
    from win32com.client import Dispatch

    app = Dispatch('Excel.Application')
    xl = app.Workbooks.Open(r'E:\PyCharm_WorkSpace\aaaa\111.xlsx')
    sht = xl.Worksheets(1)
    sht.Rows(4).Insert()
    xl.Save()
    xl.Close(SaveChanges=0)

    我说的 win32com 居然被无视了,只能上代码了。之前我也有类似 12l 的需求
    junniuLi
        23
    junniuLi  
    OP
       2020-08-26 20:06:03 +08:00
    @xiaolinjia 哈哈哈,没有没有,我去查了,只是还没找到文档,谢谢带佬 d=====( ̄▽ ̄*)b 顶
    junniuLi
        24
    junniuLi  
    OP
       2020-08-26 20:59:37 +08:00
    @xiaolinjia 带佬牛批,这个代码可以实现我说的效果,果然群除我佬
    wq2016
        25
    wq2016  
       2020-08-26 21:32:52 +08:00 via Android
    不难吧?
    xyz1396
        26
    xyz1396  
       2020-08-27 19:50:52 +08:00
    Python 输出 csv 再用宏
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2849 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 14:07 · PVG 22:07 · LAX 06:07 · JFK 09:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.