# 数据结构教程
本教程简要介绍了xlwings在读取和写入值时最常见的用例和默认行为。 有关如何使用`options`方法控制行为的深入文档,请查看[转换器和选项](converters.md)。
下面所有代码示例取决于以下导入:
~~~
>>> import xlwings as xw
~~~
## 单个单元格
默认情况下,单个单元格返回为“float”,“unicode”,“None”或“datetime”对象,具体取决于单元格是否包含数字,字符串,是否为空或表示日期:
~~~
>>> import datetime as dt
>>> sht = xw.Book().sheets[0]
>>> sht.range('A1').value = 1
>>> sht.range('A1').value
1.0
>>> sht.range('A2').value = 'Hello'
>>> sht.range('A2').value
'Hello'
>>> sht.range('A3').value is None
True
>>> sht.range('A4').value = dt.datetime(2000, 1, 1)
>>> sht.range('A4').value
datetime.datetime(2000, 1, 1, 0, 0)
~~~
## 列表
* 一维列表:表示Excel中行或列的范围作为简单列表返回,这意味着一旦它们在Python中,您就丢失了有关方向的信息。 如果这是一个问题,下一点将向您展示如何保留此信息:
~~~
>>> sht = xw.Book().sheets[0]
>>> sht.range('A1').value = [[1],[2],[3],[4],[5]] # 列方向(嵌套列表)
>>> sht.range('A1:A5').value
[1.0, 2.0, 3.0, 4.0, 5.0]
>>> sht.range('A1').value = [1, 2, 3, 4, 5]
>>> sht.range('A1:E1').value
[1.0, 2.0, 3.0, 4.0, 5.0]
~~~
要强制单个单元格作为列表到达,请使用:
```
>>> sht.range('A1').options(ndim=1).value
[1.0]
```
>[info]注意
要以列方向向Excel写入列表,请使用`transpose:sht.range('A1').options(transpose = True).value = [1,2,3,4]`
* 二维列表:如果必须保留行或列方向,请在Range选项中设置“ndim”。 这将返回Ranges作为嵌套列表(“二维列表”):
~~~
>>> sht.range('A1:A5').options(ndim=2).value
[[1.0], [2.0], [3.0], [4.0], [5.0]]
>>> sht.range('A1:E1').options(ndim=2).value
[[1.0, 2.0, 3.0, 4.0, 5.0]]
~~~
* 2维Range自动作为嵌套列表返回。 将(嵌套)列表分配给Excel中的Range时,只需将左上角的单元格指定为目标地址就足够了。 此示例还使用索引表示法将值读回到Python中:
~~~
>>> sht.range('A10').value = [['Foo 1', 'Foo 2', 'Foo 3'], [10, 20, 30]]
>>> sht.range((10,1),(11,3)).value
[['Foo 1', 'Foo 2', 'Foo 3'], [10.0, 20.0, 30.0]]
~~~
>[info]注意
尽量减少与Excel的交互次数。 执行`sht.range('A1').value = [[1,2],[3,4]]`总是比`sht.range('A1').value = [1, 2]` 和`sht.range('A2').value = [3, 4]`更有效。
## Range expanding
您可以通过`expand`方法或`options`方法中的`expand`关键字动态获取Excel范围的维度。 虽然`expand`会返回一个扩展的Range对象,但只有在访问Range的值时才会评估选项。 最好用一个例子来解释差异:
~~~
>>> 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]]
~~~
`'table'`扩展为`'down'`和`'right'`,其他可用选项分别可用于列或行扩展。
>[info]注意
将`expand()`与命名Range一起作为左上角的单元格,可以在Excel中灵活地设置:您可以在表中移动并更改其大小,而无需调整代码,例如,使用类似`sht.range('namedrange').expand().value`。
## NumPy 数组
NumPy数组的工作方式与嵌套列表类似。 但是,空单元格由`nan`而不是`None`表示。 如果要读取Range作为数组,请在`options`方法中设置`convert = np.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.]])
~~~
## Pandas DataFrames
~~~
>>> 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
# options: work for reading and writing
>>> sht.range('A5').options(index=False).value = df
>>> sht.range('A9').options(index=False, header=False).value = df
~~~
## Pandas系列
~~~
>>> import pandas as pd
>>> import numpy as np
>>> sht = xw.Book().sheets[0]
>>> s = pd.Series([1.1, 3.3, 5., np.nan, 6., 8.], name='myseries')
>>> s
0 1.1
1 3.3
2 5.0
3 NaN
4 6.0
5 8.0
Name: myseries, dtype: float64
>>> sht.range('A1').value = s
>>> sht.range('A1:B7').options(pd.Series).value
0 1.1
1 3.3
2 5.0
3 NaN
4 6.0
5 8.0
Name: myseries, dtype: float64
~~~
>[info]注意
在向Excel写入列表,NumPy数组或Pandas DataFrame时,您只需要指定左上角的单元格,例如:`sht.range('A1').value = np.eye(10)`