logo资料库

基于官方Doc的xlwings入门教程(一).pdf

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
本地磁盘
基于官方Doc的xlwings入门教程(1)
基于官方Doc的xlwings入门教程(1) In [3]: ##//// 2016/08 by YZN ////## '''xlwings教程适合给有一点点基础的用户阅读,内容参考Doc阅读''' ####导入一些模块#### import pandas as pd import numpy as np import xlwings as xw In [3]: ##///////////////////////////////////////////////////////////////////////// ////////////////////////## '#########这个部分讲怎么导入一个文件以及选取范围和切片,具体的很多选项放在教程(2)介绍 ##############' ##///////////////////////////////////////////////////////////////////////// ////////////////////////## #打开一个文件 test=xw.Book('test.xlsx') #Range的用法 xw.Range('A1').value = 'something' xw.Range('A1') xw.Range('A1:C3') xw.Range((1,1)) xw.Range((1,1), (3,3)) xw.Range('NamedRange') xw.Range(xw.Range('A1'), xw.Range('B2')) #圆括号是1-based取法,而方括号是0-based取法,xlwings遵循着app到book到sheet的层次, 以下都一样 xw.apps[0].books[0].sheets[0].range('A1') xw.apps(1).books(1).sheets(1).range('A1') xw.apps[0].books['Book1'].sheets['Sheet1'].range('A1') xw.apps(1).books('Book1').sheets('Sheet1').range('A1') #range本身也能切片,只是要记着,就是range[]里面的仍然是0-based,所以3代表第4个 >>> rng = xw.Book().sheets[0].range('A1:D5') >>> rng[0, 0] # >>> rng[1] # >>> rng[:, 3:] >>> rng[1:3, 1:3] # #其实不用range也一样吧 >>> sht = xw.Book().sheets['Sheet1'] >>> sht['A1'] # >>> sht['A1:B5'] # >>> sht[0, 1] # xlwings by Ye
基于官方Doc的xlwings入门教程(1) >>> sht[:10, :10] # In [ ]: ###//////////////////////////////////////////////////////////////## '##########################查看和赋值语句###########################' ###//////////////////////////////////////////////////////////////## ####这里你会发现给列赋值用的是多一个方括号,给行则是直接的[1,2,3,4,5] >>> sht = xw.Book().sheets[0] >>> sht.range('A1').value = [[1],[2],[3],[4],[5]] # Column orientation ( nested list) >>> sht.range('A1:A5').value [1.0, 2.0, 3.0, 4.0, 5.0] ####似乎是说也可以用下面这句话来实现对列输出 sht.range('A1').options(transpose=True).value = [1,2,3,4] >>> sht.range('A1').value = [1, 2, 3, 4, 5] >>> sht.range('A1:E1').value [1.0, 2.0, 3.0, 4.0, 5.0] ####一般来说单个单元格返回的数值是float型,你如果要让他返回的是list型可以这么做 sht.range('A1').options(ndim=1).value sht.range('A1:A5').options(ndim=2).value #也会把每个格子的值作为list放在一个li st中返回,其中2是作为list,1就是作为float sht.range('A1:E1').options(ndim=2).value #然而神奇的是,你对一行的value返回时 ,居然是list中间包含了一个大list #[[1.0, 2.0, 3.0, 4.0, 5.0]] #这边单独说明一下ndim选项,因为后续会用到,Number of array dimensions是这个选项 的意思,就是用来控制你输入的列表内元素维度 #换句话来说,xlwings是这样看待orientation的,每次在大方框下面,同一个小方框是同一 行的数据,而另一个方框则是换行了 sht.range('A1').value = [[1,2],[3,4]]#A1和B1赋值,然后换行到A2和B2赋值 In [ ]: In [ ]: ###//////////////////////////////////////////////////////////////## '##########这个单元格讲一些和array和dataframe相关的东西############' '##########请参看Converters和Options有很多的补充说明###############' ###//////////////////////////////////////////////////////////////## ####Numpy.array相关 #np的eye应该是实现几阶的单位矩阵,然后在range的option下面np.array实际上是conver t的选项,就是希望用array的方式来显示 import numpy as np >>> sht = xw.Book().sheets[0] >>> sht.range('A1').value = np.eye(3) >>> sht.range('A1').options(np.array, expand='table').value array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) type(sht.range('A1').options(np.array, expand='table').value)#这句话运行你会 发现输出了一个array对象,而不是一个数值的list ####DataFrame相关 xlwings by Ye
基于官方Doc的xlwings入门教程(1) sht = xw.Book().sheets[0] df = pd.DataFrame([[1.1, 2.2], [3.3, None]], columns=['one', 'two']) >>> df one two 0 1.1 2.2 1 3.3 NaN >>> sht.range('A1').value = df >>> sht.range('A1:C3').options(pd.DataFrame).value one two 0 1.1 2.2 1 3.3 NaN #这里读出来是一个dataframe的格式,如果你直接用range.value来读取的话,会连带index 和columns一起读进来 # options: work for reading and writing >>> sht.range('A5').options(index=False).value = df '''后面会看到Index在读取 和写入的时候作用不同''' >>> sht.range('A9').options(index=False, header=False).value = df#变成这样 以后,用range.value就可以只读出数据,应该是控制了index和columns读不读 In [ ]: ###//////////////////////////////////////////////////////////////## '##################在excel中构建xlwing的环境########################' ###//////////////////////////////////////////////////////////////## #64位电脑下载pywin32包才可以 #打开CMD,输入xlwings addin install #或者在excel中打开VB然后从xw.__path__获取安装的bas文件导入,记得文件要用xlsm保存 ['D:\\anacondas\\lib\\site-packages\\xlwings'] #xlwings quickstart myproject这个会在当前目录下创造新的支持的excel文件和.py程序文 件 In [ ]: ##///////////////////////////////////////////////////////////////////////// ///////////## '#########这一段主要讲在excel中怎么调用python,这里暂时不细说,可以参见后面的UDF#### #####' '########################UDF那里提供了Macros方法我觉得可以参考################# ##########' ##///////////////////////////////////////////////////////////////////////// ///////////## #靠RunPython程序来调用,import hello;中hello应该是.py的文件名,然后调用了world函数 #个人测试在打开VBA后用xlwings下新建一个模块来运行会比较可靠 Sub HelloWorld() RunPython ("import hello; hello.world()") End Sub # hello.py import numpy as np import xlwings as xw def world(): wb = xw.Book.caller()#仅仅在被excel调用的时候才出现 wb.sheets[0].range('A1').value = 'Hello World!' xlwings by Ye
基于官方Doc的xlwings入门教程(1) ############给了一段Debug的程序代码,这个暂时不细说#################### # my_module.py import os import xlwings as xw def my_macro(): wb = xw.Book.caller() wb.sheets[0].range('A1').value = 1 if __name__ == '__main__': # Expects the Excel file next to this source file, adjust accordingly. xw.Book('myfile.xlsxm').set_mock_caller() my_macro() ####### Sub my_macro() RunPython ("import my_module; my_module.my_macro()") End Sub In [ ]: ##///////////////////////////////////////////////////////////////## '####################又是最核心的一块,如何使用UDF##################' ##///////////////////////////////////////////////////////////////## ##UDF现在只能在Windows上运行## #xlwings quickstart myproject# ##一般来说就把文件放在要用的excel文件夹下面,或者用VBA SETTING去改PATH## '######如何操作UDF########' #####如何在一个单元格中应用UDF######## #假设现在有个a.xlsm,然后有个a.py写着下面的code import xlwings as xw @xw.func #这句话只在excel导入python的时候用到(@是个装饰符),用来给VBA指明哪个(下 一个)函数要建立wrapper def double_sum(x, y): #这个函数在VBA中也可以调用 """Returns twice the sum of the two arguments""" return 2 * (x + y) #点击AddIn的按钮import这个UDF,在某一个格子输入=double_sum(1,2)就会输出6 #######如何在一个array中应用相同的公式,或者是Doc中说的array fomula### @xw.func def add_one(data): ####首先建立一个UDF return [[cell + 1 for cell in row] for row in data] #在A1:B3输入数字,在另外一个地方选中同样大小的一个区域,输入=add_one(A1:B3),然 后摁Ctrl+Shift+Enter ,会发现公式外面有个{}这就是区域公式了 #此时可能出现了一个问题,就是你有可能对某一个单元格用了这个,你就需要如下代码来调整一 下 @xw.func @xw.arg('data', ndim=2)#这个arg应该是控制内容的一个option(argument的简称),dat a和ndim=2告诉你函数输入的【数据】应当是【2维的数组】 def add_one(data): return [[cell + 1 for cell in row] for row in data] xlwings by Ye
基于官方Doc的xlwings入门教程(1) #这是如何引入dataframe和numpy进入到函数中 import xlwings as xw import numpy as np @xw.func @xw.arg('x', np.array, ndim=2) @xw.arg('y', np.array, ndim=2) def matrix_mult(x, y): return x.dot(y) ##////////////这里Doc举了一个很好的例子,有关于计算相关系数的///////////////////## ##///////////Excel只能计算两个array之间的corr,而且比较笨重///////////////////// ## ##///////////用pandas配合xw和excel就好了/////////////////////## import xlwings as xw import pandas as pd @xw.func #你得在excel选取一块数据,需要注意的是index=和header=控制着你输入的区域是否要包含 索引!!! @xw.arg('x', pd.DataFrame, index=False, header=False) @xw.ret(index=False, header=False) #ret是控制return的 def CORREL2(x): """Like CORREL, but as array formula for more than 2 data sets""" #这个 基于某个dataframe的多列之间计算 return x.corr() '##//////////////如何在UDF的内容中调用VBA///////////////##' @xw.func @xw.arg('xl_app', vba='Application') #当设定vba的关键字为Application之后,就可 以用VBA的属性了,比如Caller.Address返回当前call的单元格区域 def get_caller_address(xl_app) return xl_app.Caller.Address ##///////////相对于从VBA中用RunPython来调用,这里提供了一种Macros方法很方便/////## import xlwings as xw #这个@xw.sub是关键,其实个人感觉就是替代了VBA中的sub过程 #一般来说我们def的东西只能在单元格或者区域引用,而加入这个之后,在AddIn导入之后你就 可以用宏来选中并运行它了 @xw.sub def my_macro(): """Writes the name of the Workbook into Range("A1") of Sheet 1""" wb = xw.Book.caller() wb.sheets[0].range('A1').value = wb.name In [ ]: ##//////////////////////////////////////////////////////////## '##############主要讲matplotlib在xlwings的使用#################' ##//////////////////////////////////////////////////////////## ####把fig这个图加入新创立的book的sheet0中 >>> import matplotlib.pyplot as plt xlwings by Ye
基于官方Doc的xlwings入门教程(1) >>> fig = plt.figurexw.apps[0].books[0].sheets[0].range('A1') >>> plt.plot([1, 2, 3, 4, 5]) >>> wb = xw.Book() >>> wb.sheets[0].pictures.add(fig, name='MyPlot', update=True)#update指的 是你在excel可以改变图片的位置和大小 ####说这个部分的作图可以完美的和excel结合####### #####使用UDF可以很方便地设定画图函数###### @xw.func def myplot(n): sht = xw.Book.caller().sheets.active fig = plt.figure() plt.plot(range(int(n))) sht.pictures.add(fig, name='MyPlot', update=True) return 'Plotted with n={}'.format(n) #然后在xlwings的addin下把这个玩意import,在B2格直接输入=myplot(B1),B1中写个 5,就可以实现自动画图了 ####你可以改变图的大小和位置##### sht = xw.Book().sheets[0] >>> sht.pictures.add(fig, name='MyPlot', update=True,left=sht.range('B5') .left, top=sht.range('B5').top) #或者 >>> plot = sht.pictures.add(fig, name='MyPlot', update=True) >>> plot.height /= 2 >>> plot.width /= 2 #####也可以通过pandas来画画### import pandas as pd import numpy as np df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd']) ax = df.plot(kind='bar') fig = ax.get_figure() In [ ]: ##///////////////////////////////////////////////////////////////////////// ///////////## '#########################最后一个也是非常重要的部分,Converters和Options####### #########' ##///////////////////////////////////////////////////////////////////////// ///////////## ##简单理解来看converters可以在你读取或者写入Excel的时候对对象类型进行匹配### '''常见的就是用在Range的option内,以及应用UDF的时候,而且务必注意converters区分读取 和写入的情况!''' #在之前的例子里面我们就见到很多这样的语句,设定读取或写入的格式,比如 @xw.arg('x', pd.DataFrame, index=False, header=False) #这里就是制定了DataFra me作为形式 sht.range('A1:E1').options(ndim=2).value #这里用了default的形式,只是说明数据类 型为二维 ####介绍一些default的converters###### '''u'单个Cell根据里面是数值还是文字或是日期分为float,unicode以及datetime三种,以及 空的None'''' '''而一维数据作为list,二维或者多维就是nested list,多重的list''' xlwings by Ye
基于官方Doc的xlwings入门教程(1) '''///////////////一些常用的可以设定的converters内容介绍//////////////////''' ##----- ndim:这个介绍过了 -------## ##----- number:设置单元格数值是float还是int -----## sht.range('A1').options(numbers=int).value '''这里是读取的时候用int来展示''' @xw.arg('x', numbers=int)'''这里是所有输入的x参数的number都被设定成int''' ##----- dates: 用来设定日期时间格式,决定是日期还是‘日期+时间’的格式 -----## '''对Range使用的时候,通俗易懂不解释''' >>> import datetime as dt >>> sht.range('A1').options(dates=dt.date).value '''在UDF中格式化的时候''' ###这里的lambda函数不细说,可以理解成一个针对每个参数都进行的转换过程(非定义的临时函 数),**kwargs是可变参数,%04i表示‘格式+位数+形式’ >>> my_date_handler = lambda year, month, day, **kwargs: "%04i-%02i-%02i" % (year, month, day) >>> sht.range('A1').options(dates=my_date_handler).value '2017-02-20' ##----- empty=‘NA’ 你可以设置空值的形式,而不是None -----## ##----- transpose:可以用一个list对column进行输出 ,后面也会看到它起到转置的作用 -----## sht.range('A1').options(transpose=True).value = [1, 2, 3] #之前有提到输出某 一列要[[1],[2],[3]] ,现在用这句就可以 ##------------ expand(只在Range中有用):具体参看下方,除了table,还有vertical 和horizontal 可以选择 -----------## ######特别需要注意,‘gives back an expanded Range object, options are only ev aluated when accessing the values of a Range.’大概就是说 ######expand函数返回的是一个直接由range函数定义的扩展区域,也就是说是针对某一个单元格 进行range一个list后的区域,即使相邻区域有东西也不要 ######option中的expand是我们理解的excel中的,凡是基于这个单元周围有数值的全选中(测试 了一下,似乎有空值就不会选中) ######table指的是方式,即先down再right,因此定义的是左上角单元格,也有单独选行或者列的 sht = xw.Book().sheets[0] >>> sht.range('A1').value = [[1,2], [3,4]] >>> rng1 = sht.range('A1').expand('table') # or just .expand() >>> rng2 = sht.range('A1').options(expand='table') >>> rng1.value #[[1.0, 2.0], [3.0, 4.0]] >>> rng2.value #[[1.0, 2.0], [3.0, 4.0]] >>> sht.range('A3').value = [5, 6] >>> rng1.value #[[1.0, 2.0], [3.0, 4.0]] >>> rng2.value #[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]] '''///////////一些BuiltIn的参数介绍/////////////////''' xlwings by Ye
基于官方Doc的xlwings入门教程(1) ##----- dict:可以把两列变成一个字典进行匹配 -----## >>> sht = xw.sheets.active >>> sht.range('A1:B2').options(dict).value {'a': 1.0, 'b': 2.0} >>> sht.range('A4:B5').options(dict, transpose=True).value {'a': 1.0, 'b': 2.0} ##----- numpy的array属性,这个之前介绍过 -----## sht.range('A1:A3').options(np.array, ndim=2).value array([[ 1.], [ 2.], [ 3.]]) ##----- Pandas的Series:之前没有详细介绍 -----## '''Index在写入的时候类似于pandas的index_col设定把哪一列作为index展示,而读取的时候为 布尔值,是否将数据输入进index''' '''header如果在读取时为False,则不会显示index和column,写入时是否包含了index或者col umn的name,注意!是index的name而非index本身''' '''主要写一下Index和header属性,DataFrame也是类似的,除了header在读取时是显示将前几 行作为列的标签''' ##这里补充一下,header这个属性,按照越上方的行层次越高,如果第一行[a,a,b]下一行[d,e,f ],那么双重的column索引,d和e都属于a类,第二个a不显示 >>> sht = xw.Book().sheets[0] >>> s = sht.range('A1').options(pd.Series, expand='table').value >>> s date 2001-01-01 1 2001-01-02 2 2001-01-03 3 Name: series name, dtype: float64 >>> sht.range('D1', header=False).value = s ##----- raw:这个能提取原始的东西,就是原来excel写了啥就提取出啥 -----## >>> sht.range('A1:B2').value [[1.0, 'text'], [datetime.datetime(2016, 2, 1, 0, 0), None]] >>> sht.range('A1:B2').options('raw').value # or sht.range('A1:B2').raw_v alue ((1.0, 'text'), (pywintypes.datetime(2016, 2, 1, 0, 0, tzinfo=TimeZoneInfo ('GMT Standard Time', True)), None)) In [ ]: ##///////////////////////////////////////////////////////////////////////// ///////////## '#########################单独将Custom converters抽出来讲一下,自定义转换####### #########' ##///////////////////////////////////////////////////////////////////////// ///////////## '''定义一个contervers需要特别注意是read_value or write_value,这里以扩展原来的Dat aFrame为例''' from xlwings.conversion import Converter, PandasDataFrameConverter class DataFrameDropna(Converter): ##类的概念暂时不管,记住这个形式 xlwings by Ye
分享到:
收藏