excel中想實現使用Python代替VBA,請問應該怎麼做?

前提:因使用VBA代碼可讀性和 擴展性差,想用Python實現,以提高 復用率。

目前的想法是 在Excel中寫入基礎信息,執行宏時,VBA中通過庫調用Python代碼,生成統計數據,請問可以使用什麼庫來實現?


維護一個基於Excel的項目5年的苦逼怒答。「python(或者其他什麼語言)操作excel」文件,按是否依賴Excel,可以分為兩類。

第一類,excel文件只是用來存儲數據,python對它的操作只是讀和寫。這種時候,對文件的操作不需要依賴Excel,你的機器上沒有excel也能執行。在這種場景下,csv,txt等Excel支持的文本文件格式,都是很好的選擇。這種情況,所謂的"python讀寫excel文件",實際上就是python讀寫文本文件,無非是這個文本文件是有一定格式的,找個csv的類庫處理能事半功倍。如果csv/txt太過簡單,文件內需要多個worksheet,那麼可以保存為xls/xlsx格式,對應的讀寫操作用樓上提到的xlrd和openpyxl。

第二類,對文件的操作不止讀寫數據,包含更多的其他操作,比如插入行列,設置字體顏色,等待。這時候文件格式必然是excel only的格式(xls*)。對應的操作,其實最基礎的,是通過COM調用Excel的API,實際上VBA調用的也是這個東西。python,以及其他很多語言,都是支持COM的,在腳本裡面獲取到了Excel.Application,就可以像在VBA裡面一樣寫Application.Workbooks(1).Worksheet(1)了。下面sample是ruby寫的,python應該也差不多。

#引用COM

require "win32ole"

#連接一個已經打開的Excel

xlApp = WIN32OLE.connect("Excel.Application")

#接下去就和VBA的寫法沒什麼兩樣了

wb = xlApp.activeWorkbook #獲取當前激活的workbook

ws = wb.worksheets(1) #獲取第一個worksheet

ws.range("A1").value = "hello" #在sheet1的A1寫入「hello」


搜索pyxll,你值得擁有


有了xlwings,excel就成了個gui了,結合numpy,pandas各種爽。

還有比如直接插入matplotlib圖表,比如利用python自帶的sort一行代碼完成vba寫個幾十行大一百行才能完成的複雜排序。

剛看了下新版api,又有新的黑科技了,可以excel裝個插件然後用python來寫自定義公式


最近在用 Python 操作 excel ,推薦一個模塊吧,

GitHub - pyexcel/pyexcel: Python Wrapper that provides one API for reading, manipulating and writing data in csv, ods, xls, xlsx and xlsm files

這個第三方的模塊在格式之間的轉換比較方便。

另外推薦 awesome-Python GitHub - vinta/awesome-python: A curated list of awesome Python frameworks, libraries, software and resources 想用 Python 做點什麼,直接去找相應的模塊就好了。

因為我要讀入比較大的 excel 的文件, 最後使用了 openpyxl 的read_only 的模式,這樣讀入的速度比較快。

下面是一個把比較大的 xlsx 文件轉為 csv 文件的實例。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import openpyxl
import csv

def xlsx_to_csv(fn):
wb = openpyxl.load_workbook(filename=fn, read_only=True)
sheet_name = wb.get_sheet_names()
sheet = wb[sheet_name[0]] # 選擇操作 excel 文件的第一張表
with open("sample.csv", "w", newline="", encoding="utf-8") as fw:
ww = csv.writer(fw)
for r in sheet.rows:
row = [i.value for i in r]
ww.writerow(row)

if __name__ == "__main__":
fn = "sample.xlsx"
xlsx_to_csv(fn)

文件都讀入到 Python 中了,操作起來不就方便多了。

另外最新在我的微信公眾號,更新一篇介紹 xlwings 的文章,http://mp.weixin.qq.com/s/40VdZail2gyOhbUpocoTpQ


考不考慮R語言?


在你的VBA里將所需要的數據導出到一個新文件,用VBA調用CMD,CMD運行一條執行蟒蛇的語句,可以讓VBA通過CMD往蟒蛇里傳參,蟒蛇運行,蟒蛇輸出結果到某個指定好了的空文件夾下,VBA循環監聽空文件夾下文件數目如果為1,則讀取新文件內容,這樣就極大的擴展了VBA的使用範圍了。

這只是一條簡單的思路,可任意完善,只要能達到目的。

一般來說主流程序系統由vba改成其他項目還是非常困難的。

如果採用蟒蛇控制Excel,那就平添太多學習成本。既然會了excel,會了蟒蛇數據處理,那就各取所長,就用我說的方法。


改用C#也可以,不需要一定用VBA。而且根據政策,等以後移植到UWP之後,都用C#了。


我想用js…逃跑ε=(′o`)


我曾經也有這樣的想法,因為實在很難適應vba的語法,寫一會vba,再寫別的就各種掰不回來。

樓上各位提到的工具多少也試過,都沒成功。

最後我用了一種曲線救國的方法:

1.先用vba寫導出json的函數,注意,是函數,可以把excel里的數據直接轉化為json並直接保存,每次源數據變化都會重新導出並保存。

2.用python讀取json數據,進行運算,眾所周知,python讀取json的方法是很友好的

當然缺點就是,這種方式只能用於運算數據,不能更改excel的數據


如果數據是 xlsx 格式的文件的話,大膽把 Excel 當成一個可視化工具,直接用 openpyxl 整個讀出來操作,再寫回去,包括樣式,公式之類的都可以修改。


對於會用python的人,Excel現在唯一重要的是最後的數據呈現。大多數你的領導或者客戶還是習慣看格式好的excel,而不是CSV。顯然沒有人喜歡寫完數據處理腳本後還要手動調整excel格式。問題應該是如何用python控制excelVBA製表!

根據@woodylic的答案找到了對應的包名叫pywin32, 這個包在anaconda中自帶.

另外引用木雨山的博客內容

python模塊:win32com用法詳解

使用技巧

import win32com

from win32com.client import Dispatch, constants

w = win32com.client.Dispatch("Word.Application")

# 或者使用下面的方法,使用啟動獨立的進程:

# w = win32com.client.DispatchEx("Word.Application")

# 後台運行,不顯示,不警告

w.Visible = 0

w.DisplayAlerts = 0

# 打開新的文件

doc = w.Documents.Open( FileName = filenamein )

# worddoc = w.Documents.Add() # 創建新的文檔

# 插入文字

myRange = doc.Range(0,0)

myRange.InsertBefore("Hello from Python!")

# 使用樣式

wordSel = myRange.Select()

wordSel.Style = constants.wdStyleHeading1

# 正文文字替換

w.Selection.Find.ClearFormatting()

w.Selection.Find.Replacement.ClearFormatting()

w.Selection.Find.Execute(OldStr, False, False, False, False, False, True, 1, True, NewStr, 2)

# 頁眉文字替換

w.ActiveDocument.Sections[0].Headers[0].Range.Find.ClearFormatting()

w.ActiveDocument.Sections[0].Headers[0].Range.Find.Replacement.ClearFormatting()

w.ActiveDocument.Sections[0].Headers[0].Range.Find.Execute(OldStr, False, False, False, False, False, True, 1, False, NewStr, 2)

# 表格操作

doc.Tables[0].Rows[0].Cells[0].Range.Text ="123123"

worddoc.Tables[0].Rows.Add() # 增加一行

# 轉換為html

wc = win32com.client.constants

w.ActiveDocument.WebOptions.RelyOnCSS = 1

w.ActiveDocument.WebOptions.OptimizeForBrowser = 1

w.ActiveDocument.WebOptions.BrowserLevel = 0 # constants.wdBrowserLevelV4

w.ActiveDocument.WebOptions.OrganizeInFolder = 0

w.ActiveDocument.WebOptions.UseLongFileNames = 1

w.ActiveDocument.WebOptions.RelyOnVML = 0

w.ActiveDocument.WebOptions.AllowPNG = 1

w.ActiveDocument.SaveAs( FileName = filenameout, FileFormat = wc.wdFormatHTML )

# 列印

doc.PrintOut()

# 關閉

# doc.Close()

w.Documents.Close(wc.wdDoNotSaveChanges)

w.Quit()

(3)處理excel

[1]使用PyExcelerator讀寫EXCEL文件(Platform: Win,Unix-like)

優點:簡單易用 缺點:不可改變已存在的EXCEL文件。

PyExcelerator是一個開源的MS Excel文件處理python包。它主要是用來寫 Excel 文件.URL: pyExcelerator download

我沒有找到關於PyExcelerator的文檔。只是看到了limodou的一篇介紹。

http://blog.donews.com/limodou/archive/2005/07/09/460033.aspx

這個包使用起來還是比較簡單的:)。帶了很多小例子,可以參照。

例mini.py.

=================================

#!/usr/bin/env python

# -*- coding: windows-1251 -*-

# Copyright (C) 2005 Kiseliov Roman

__rev_id__ = """$Id: mini.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""

"導入模塊

from pyExcelerator import *

"生成一個工作薄

w = Workbook()

"加入一個Sheet

ws = w.add_sheet("Hey, Dude")

"保存

w.save("mini.xls")

=================================

[2]使用COM介面,直接操作EXCEL(只能在Win上)

優點:可以滿足絕大數要求。缺點:有些麻煩。:-)

這方面的例子很多,GOOGLE 看吧:-). 文檔也可以參看OFFICE自帶的VBA EXCEL 幫助文件(VBAXL.CHM)。這裡面講述了EXCEL VBA的編程概念,

不錯的教程!另外,《Python Programming on Win32》書中也有很詳細的介紹。這本書中給出了一個類來操作EXCEL 文件,可以很容易的加以擴展。

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from win32com.client import Dispatch

import win32com.client

class easyExcel:

"""A utility to make it easier to get at Excel. Remembering

to save the data is your problem, as is error handling.

Operates on one workbook at a time."""

def __init__(self, filename=None):

self.xlApp = win32com.client.Dispatch("Excel.Application")

if filename:

self.filename = filename

self.xlBook = self.xlApp.Workbooks.Open(filename)

else:

self.xlBook = self.xlApp.Workbooks.Add()

self.filename = ""

def save(self, newfilename=None):

if newfilename:

self.filename = newfilename

self.xlBook.SaveAs(newfilename)

else:

self.xlBook.Save()

def close(self):

self.xlBook.Close(SaveChanges=0)

del self.xlApp

def getCell(self, sheet, row, col):

"Get value of one cell"

sht = self.xlBook.Worksheets(sheet)

return sht.Cells(row, col).Value

def setCell(self, sheet, row, col, value):

"set value of one cell"

sht = self.xlBook.Worksheets(sheet)

sht.Cells(row, col).Value = value

def getRange(self, sheet, row1, col1, row2, col2):

"return a 2d array (i.e. tuple of tuples)"

sht = self.xlBook.Worksheets(sheet)

return sht.Range(sht.Cells(row1, col1), sht.Cells(row2, col2)).Value

def addPicture(self, sheet, pictureName, Left, Top, Width, Height):

"Insert a picture in sheet"

sht = self.xlBook.Worksheets(sheet)

sht.Shapes.AddPicture(pictureName, 1, 1, Left, Top, Width, Height)

def cpSheet(self, before):

"copy sheet"

shts = self.xlBook.Worksheets

shts(1).Copy(None,shts(1))

"下面是一些測試代碼。

if __name__ == "__main__":

PNFILE = r"c:screenshot.bmp"

xls = easyExcel(r"D: est.xls")

xls.addPicture("Sheet1", PNFILE, 20,20,1000,1000)

xls.cpSheet("Sheet1")

xls.save()

xls.close()

(4)python調用簡訊貓控制項,發簡訊

#! /usr/bin/env python

#coding=gbk

import sys

import win32com.client

ocxname="ShouYan_SmsGate61.Smsgate"

axocx=win32com.client.Dispatch(ocxname)

axocx.CommPort=8#設置COM埠號

axocx.SmsService="+8613800100500"#設置簡訊服務號碼

axocx.Settings="9600,n,8,1"#設置com埠速度

axocx.sn="loyin"

c=axocx.Connect(1)#連接簡訊貓或手機

print "連接情況",axocx.Link()

axocx.SendSms("python確實是很好的","15101021000",0)#發送簡訊


沒太明白題主的具體需求是什麼,我現在工作中也用python處理excel,主要是做一些對excel文件的行列轉化、按條件抽取數據、計算。主要用下面的一些方式:

  1. 把excel文件處理稱文本格式。主要方式是用vba來保存成CSV、TXT的格式。

  2. 用python的pandas庫對csv、txt、進行各種變化、處理,pandas非常強大。

轉化成csv、txt格式,然後用python處理,這種處理方式,程序的擴展性應該會比較好一些。

如果直接讀excel,改變excel表格的基本信息(獲取合併的單元格、改變單元格樣式等),我了解的有兩個:

  • openpyxl(openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm files),不過這個只支持2010以上的xlsx文件。

  • xlrd https://pypi.python.org/pypi/xlrd 支持xls和xlsx文件。

xlrd基本上沒怎麼用過,openpyxl用過幾次,感覺功能還不錯。


這個問題我覺得我還是有點專業的,雖不是財務,但是大量處理財務數據。

背景:公司程序員是絕對不可能給我一個資料庫賬號的,就算只有讀許可權也不行。公司內網web系統auth不完善,我可以輕鬆繞過許可權爬數據。

起初,用xlrd和xlwt。後來發現這兩個工具寫起來有點麻煩,而且性能不是很優秀。於是改用內置的csv模塊。在這個階段,自動化程度不高,需要大量人工干預和預先處理

現在因為數據量大了,我就在本地弄了個lnmp環境和navicat,將paypal原始數據導入,操作資料庫。現在正在寫這方面的腳本,結合email模塊和windows計劃任務完成全部自動化。


SolverStudio for Excel 支持C# Python等,有沒有人試過?

"An integrated environment for optimisation using modelling languages within Excel"

Developing for Excel

If you are interested in developing for Excel, you might like the following resources.

Excel XLL add-in libary for writing C++ add-ins using Visual Studio 2010 (incl Express): Excel xll add-in library

Excel-DNA provides .net integration with Excel: Excel-DNA - Home

PyXLL, a 「free for non-commercial and evaluation purposes」 Excel extension, allows Python code to be used to add menus and user functions within Excel.

Pycel will compile a spreadsheet into Python. It was developed to allow non-linear optimisation of aircraft design.

PyWorkbooks is an open source Python interface for Excel and GNumeric; it looks very nice, with careful thought given to speed issues (e.g. implenting Generators).

Python for Excel (PFE) is a commercial (?) Python scripting system for Excel that 「provides a complete set of tools for building of fully featured applications with Excel front end. It is in-process control of Excel with an out-of-process developement and debugging environment.」


有openpyxl讀寫包 ,讀寫分離的包xlrd,xlwt包。


datanitro


等,馬上就要官方實現了。


xlwings,一個包解決所有問題


我覺得題主想問的主要是提高靈活性和利用率。用python完全可以實現。

題主打算用excel去展現,用宏去調用python腳本這可能是因為vba是這樣的模式,但python完全不用這樣做。

題主可以把excel為主換成以python為主,用python實現需要實現的功能,然後將處理好的數據存到excel中。或者先讀入excel處理好後再去修改原excel。

用到的庫有xlrd用於讀 xlwt用於寫。這兩個庫就夠一般操作了。


cython也不能脫離python runtime。那個python.dll還是要的。excel調用python沒問題。可以用pywin32,支持com。

我原來也用過,用python寫了一個函數,在excel調用。

你這個需求感覺用cx freeze包裝一下,在客戶端安裝就行了,不需要動用cython。


推薦閱讀:

如何優雅的安裝Python的pandas?
怎樣使 Python 輸出時不換行?
Python 的縮進有多重要?
Python沒有常量是不是不夠安全的設計?
Python的Dictionary的花括弧,應該換行嗎?

TAG:Python | MicrosoftExcel | Cython |