你好,这里是BIM的乐趣,我是九哥~
今天我们来聊聊如何通过Dynamo处理Excel数据以及格式,Dynamo自带的节点肯定是不行,所以我们需要来用Python解决(当然有个节点包
Bumblebee,我在案例百解教程里有过介绍),常用的处理Excel的python模块有很多,如xlrd,xlwt,xlutils,openpyxl,XlsxWriter,会Python的小伙伴自己去玩了哈,但是Dynamo目前主要是用IronPython(2.10+版本除外),所以我们可选的就没啥了,乖乖用Microsoft.Office.Interop.Excel就好了。
不了解这个的话,可以先关注下官方API网站:
Microsoft.Office.Interop.Excel Namespace | Microsoft Docs
#网址如下:
Microsoft.Office.Interop.Excel Namespace | Microsoft Learn
过多的我感觉也没啥可讲的,我把每行代码是在做什么,在Dynamo中来注释下,方便小伙伴们理解。好了,接下来先演示下基本用法:
一、读取Excel内容:
写个和Dynamo自带节点类似的:
import clr
import sys
import System
from System import Array
from System.Collections.Generic import *
#引入Microsoft.Office.Interop.Excel.dll模块
clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
from Microsoft.Office.Interop import Excel
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo("en-US")
from System.Runtime.InteropServices import Marshal
def fun(col_int):#数字转换成Excel列号
list1=['A','B','C','D','E','F','G','H','I',
'J','K','L','M','N','O','P','Q','R',
'S','T','U','V','W','X','Y','Z']
col_str=''
if(col_int<=26):
col_str=list1[col_int-1]
elif(col_int < 702):
col_int=col_int-27
col_str=list1[int(col_int/26)]+list1[int(col_int%26)]
elif(col_int==702):
col_str='ZZ'
else:
col_int=col_int-703
col_str=list1[int(col_int/676)]+list1[int(col_int/26)%26]+list1[col_int%26]
return(col_str)
file = IN[0]
#打开Excel应用程序
excel = Excel.ApplicationClass()
bool = IN[2] #Excel是否可见
excel.Visible = bool
wb = excel.Workbooks.Open(file)
#输入要打开的Excel工作表名称
sheetName = IN[1]
ws = wb.Worksheets[sheetName]
#获取Excel的总行数和列数
totalColumns = ws.UsedRange.Columns.Count
totalRows = ws.UsedRange.Rows.Count
x = (fun(totalColumns))
data = []
for i in range(totalRows):
x1range = ws.Range("A"+str(i+1),str(x)+str(i+1)) #读取某一行的内容
r1 = x1range.Value2
data.append(r1)
i += 1
OUT = data
二、写入Excel内容
写个和Dynamo自带节点类似的:
import clr
import sys
import System
from System import Array
from System.Collections.Generic import *
#引入Microsoft.Office.Interop.Excel.dll模块
clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
from Microsoft.Office.Interop import Excel
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo("en-US")
from System.Runtime.InteropServices import Marshal
def fun(col_int):#数字转换成Excel列号
list1=['A','B','C','D','E','F','G','H','I',
'J','K','L','M','N','O','P','Q','R',
'S','T','U','V','W','X','Y','Z']
col_str=''
if(col_int<=26):
col_str=list1[col_int-1]
elif(col_int < 702):
col_int=col_int-27
col_str=list1[int(col_int/26)]+list1[int(col_int%26)]
elif(col_int==702):
col_str='ZZ'
else:
col_int=col_int-703
col_str=list1[int(col_int/676)]+list1[int(col_int/26)%26]+list1[col_int%26]
return(col_str)
file = IN[0] #文件
sheetName = IN[1] #sheetName
#打开Excel软件
ExcelApp = Excel.ApplicationClass()
ExcelApp.Visible = True #Excel可见
#新建Excel表格
wb = ExcelApp.Workbooks.Add() #新建Excel文件
ws = wb.Worksheets.Add() #新建表格
ws.Name = sheetName #给表格命名
ws = wb.Worksheets[sheetName] #激活该表格,可省略
row = IN[2] #行
col = IN[3] #列
data = IN[4] #数据
for d in data:
x1 = row
y1 = fun(col)
for i in range(len(d)):
ws.Range[str(y1)+str(x1)].Value = d[i]#.ToString()
x1 += 1
col += 1
#保存Excel文件到指定目录
wb.SaveAs(file)
OUT = "数据写入成功"
三、数字转换为Excel列号
这里简单写了一个自定义函数,来把输入的数字转换为Excel的列号,就是一顿数学计算,没啥好解释的,如下:
def fun(col_int):#数字转换成Excel列号
list1=['A','B','C','D','E','F','G','H','I',
'J','K','L','M','N','O','P','Q','R',
'S','T','U','V','W','X','Y','Z']
col_str=''
if(col_int<=26):
col_str=list1[col_int-1]
elif(col_int < 702):
col_int=col_int-27
col_str=list1[int(col_int/26)]+list1[int(col_int%26)]
elif(col_int==702):
col_str='ZZ'
else:
col_int=col_int-703
col_str=list1[int(col_int/676)]+list1[int(col_int/26)%26]+list1[col_int%26]
return(col_str)
这个存下来吧,通用函数,很方便:
四、Excel格式的基本设置
(一)枚举一些基本的Excel格式设置的代码:
#ws为已经打开的Excel表格,以A1格位置为例:
#单个格写入内容
ws.Range["A1"].Value = "门窗表"
#设置字号
ws.Range["A1"].Font.Size = 15
#设置文字加粗
ws.Range["A1"].Font.Bold = True
#合并单元格,A1到A3合并
ws.Range("A1:C1").MergeCells = True
#自动换行
ws.Range("A1").WrapText = True
#自动列宽
ws.Range("A1").EntireColumn.AutoFit()
#文字居中
ws.Range("A1").HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter
#设置字体为黑体
ws.Range("A1").Font.Name= "黑体"
(二)边框样式设置,API截图如下:
#设置表格边线样式,以黑实线为例:
#wb为当前打开Excel,ActiveSheet为当前激活的表格:
#rng为要设置边框的表格范围
#Excel.XlLineStyle.xlContinuous为实线
#范围的最底部边线
wb.ActiveSheet.Range(rng).Borders.Item(Excel.XlBordersIndex.xlEdgeBottom).LineStyle = Excel.XlLineStyle.xlContinuous
#范围的最左侧边线
wb.ActiveSheet.Range(rng).Borders.Item(Excel.XlBordersIndex.xlEdgeLeft).LineStyle = Excel.XlLineStyle.xlContinuous
#范围的最右侧边线
wb.ActiveSheet.Range(rng).Borders.Item(Excel.XlBordersIndex.xlEdgeRight).LineStyle = Excel.XlLineStyle.xlContinuous
#范围的最顶部边线
wb.ActiveSheet.Range(rng).Borders.Item(Excel.XlBordersIndex.xlEdgeTop).LineStyle = Excel.XlLineStyle.xlContinuous
#范围内的水平线
wb.ActiveSheet.Range(rng).Borders.Item(Excel.XlBordersIndex.xlInsideHorizontal).LineStyle = Excel.XlLineStyle.xlContinuous
#范围内的垂直线
wb.ActiveSheet.Range(rng).Borders.Item(Excel.XlBordersIndex.xlInsideVertical).LineStyle = Excel.XlLineStyle.xlContinuous
(三)设置颜色:
#设置填充颜色为淡紫色
ws.Range.Interior.ColorIndex = 39
#Excel字体颜色比较特殊,都是int表示的,需要转换一下,方法如下:
clr.AddReference("System.Drawing")
from System.Drawing import *
ws.Range["A1"].Font.Color = ColorTranslator.ToOle(Color.Orange)
色号如下图:
(四)单元格格式
#常规
ws.Range("A1").NumberFormatlocal = "G/通用格式"
#数值
#保留小数位数为3 (此处“_”表示:留下一个与下一个字符同等宽度的空格)
ws.Range("A1").NumberFormatlocal = "0.000"
#不要小数
ws.Range("A1").NumberFormatlocal = "0"
#保留小数位数为3,并使用千位分隔符
ws.Range("A1").NumberFormatlo cal = "#,##0.000"
#货币
ws.Range("A1").NumberFormatlocal = "$#,##0.000"
#百分比
ws.Range("A1").NumberFormatlocal = "0.000%"
#分数
ws.Range("A1").NumberFormatlocal = "# ?/?"
#科学计数
ws.Range("A1").NumberFormatlocal = "0.00E+00"
#文本
ws.Range("A1").NumberFormatlocal = "@"
#特殊
#邮政编码
ws.Range("A1").NumberFormatlocal = "000000"
#中文小写数字
ws.Range("A1").NumberFormatlocal = "[DBNum1]G/通用格式"
#中文大写胡子
ws.Range("A1").NumberFormatlocal = "[DBNum2]G/通用格式"
#人民币大写
ws.Range("A1").NumberFormatlocal = "[DBNum2][$RMB]G/通用格式"
篇幅有限,今天就整理这些吧,有需求,多去翻翻官方API就行了~