先发下牢骚,由于某个家长不负责任的行为导致我家这片区域的小孩上了一个星期的网课。。。
神兽在家,除了上网课,小奔运动打卡,写字和计算练习当然也要安排上
出计算练习题当然也不可能手写,刚好以前做土地确权时用ArcMap批量输出过地块示意图的PDF,出计算练习题就更简单了,就用到了文本框,连图层都不用加,数据驱动页面也不需要使用
首先要自己制作两个Python脚本工具
Python脚本工具的制作可以学习帮助文档
还可以参考
ArcMap自定义脚本工具制作
https://liyuanxiang.blog.csdn.net/article/details/52774278
新建一个ArcMap工程
在工程的工作目录右键新建一个『工具箱』
右键点击建好的『计算练习』工具箱添加Python脚本,生成『批量创建文本框』工具
右键点击建好的『计算练习』工具箱添加Python脚本,生成『批量输出PDF』工具,『批量输出PDF』工具设置了两个长整型参数:『最大整数』和『输出页数』
『最大整数』是参与计算的最大整数
『输出页数』是输出PDF的页数
『最大整数』和『输出页数』两个参数可以设置范围和默认值
我这里设置的范围是0到100,默认值是10
在ArcMap中无法直接用Python代码凭空创建文本框(或许是我没找到),但可以调用现有的文本框的clone方法,生成新的文本框,因此要在工程里先添加文本框
在页面视图先把图层框移到页面外,再添加一个文本框作每一页的标题,就叫『计算练习』吧
然后再添加一个文本框作为要新建计算式文本框的母框,设置好字体对齐等,这个母框的名字在代码中会被调用
使用『批量创建文本框』工具生成文本框
后面生成的文本框都会克隆母框的属性,但名字会以母框名字为基础自动叠加
使用『批量输出PDF』工具输出PDF
下面是『批量创建文本框』工具的代码:
import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT") #获取当前工程
tableText = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "ZXtext")[0] #获取当前工程中名字为“ZXtext”的文本框
# 克隆100个文本框,调整位置,均匀分布成25行4列
Y = 28.0
for num in range(1, 26):
NewY = Y - num
newTxt1 = tableText.clone() #克隆母框
newTxt1.elementPositionX = 1.0 #设置文本框锚点位置的X值
newTxt1.elementPositionY = NewY #设置文本框锚点位置的Y值
newTxt1.text = newTxt1.name #将文本框的文本内容赋值为文本框的名字
newTxt2 = tableText.clone()
newTxt2.elementPositionX = 6.0
newTxt2.elementPositionY = NewY
newTxt2.text = newTxt2.name
newTxt3 = tableText.clone()
newTxt3.elementPositionX = 11.0
newTxt3.elementPositionY = NewY
newTxt3.text = newTxt3.name
newTxt4 = tableText.clone()
newTxt4.elementPositionX = 16.0
newTxt4.elementPositionY = NewY
newTxt4.text = newTxt4.name
Y -= 0.08
mxd.save() #保存工程
del mxd
下面是『批量输出PDF』工具的代码:
import arcpy, os, random
zuidazhengshu = arcpy.GetParameterAsText(0) #以字符串的形式返回参数列表第一个参数的值,最大整数
shuchuyeshu = arcpy.GetParameterAsText(1) #以字符串的形式返回参数列表第二个参数的值,输出页数
zxint1=int(zuidazhengshu) #字符串转为整数
zxint2=int(shuchuyeshu) #字符串转为整数
zx1=zxint1+1
liebiao1=[]
liebiao2=[]
liebiao3=[]
liebiao4=[]
liebiao5=[]
path1=os.path.dirname(__file__) #获取当前脚本所在路径
path2=path1 + u"\u005c"+u"\u51fa\u9898"+ u"\u005c" #在当前脚本所在路径后添加“\出题\”
# 判断当前脚本所在文件夹中是否有“出题”文件夹,如果没有就创建
if not os.path.exists(path2):
os.mkdir(path2)
finalpdf_filename = path2 + "chuti3.pdf" #设置输出PDF的路径
# 判断“出题”文件夹中是否有“chuti3.pdf”,如果有就删除
if os.path.exists(finalpdf_filename):
os.remove(finalpdf_filename)
finalPdf = arcpy.mapping.PDFDocumentCreate(finalpdf_filename) #在“出题”文件夹中创建PDF文件“chuti3.pdf”
temp_filename = path2 + "zxtemp3.pdf" #设置临时PDF的路径
# 生成文本框的名字,追加到列表liebiao1
for num in range(1,101):
zifunum="ZXtext_%d"%num
liebiao1.append(zifunum)
# 生成加法计算式列表liebiao2,形如:["1+1=","1+2=",...,"10+10="]
for i1 in range(1,zx1):
for j1 in range(1,zx1):
zxs1="%d+%d="%(i1,j1)
liebiao2.append(zxs1)
# 生成减法计算式列表liebiao3,形如["2-1=","3-1=","3-2=",...,"10-9="]
for i2 in range(2,zx1):
for j2 in range(1,i2):
zxs2="%d-%d="%(i2,j2)
liebiao3.append(zxs2)
# 生成含0计算式列表liebiao4,形如["0+1=","1+0=","1-1=",...,"0+10=","10+0=","10-10="]
liebiao4.append("0+0=")
for i3 in range(1,zx1):
zxs3="0+%d="%i3
zxs4="%d+0="%i3
zxs5="%d-%d="%(i3,i3)
liebiao4.append(zxs3)
liebiao4.append(zxs4)
liebiao4.append(zxs5)
mxd = arcpy.mapping.MapDocument("CURRENT") #获取当前工程
# 批量生成临时PDF,追加到“chuti3.pdf”中
for pageNum in range(1, zxint2 + 1):
templist1=random.sample(liebiao2,75) #从加法计算式列表liebiao2中随机抽取75个生成新列表,顺序打乱且不重复
templist2=random.sample(liebiao3,20) #从减法计算式列表liebiao2中随机抽取20个生成新列表,顺序打乱且不重复
templist3=random.sample(liebiao4,5) #从含0计算式列表liebiao2中随机抽取5个生成新列表,顺序打乱且不重复
templist4=templist1+templist2+templist3 #组合生成新列表templist4
liebiao5=random.sample(templist4,100) #从新列表templist4中随机抽取100个生成列表liebiao5,顺序打乱且不重复
if len(liebiao1)==100 and len(liebiao5)==100: #判断两个列表中元素是否都是100
for i in range(0,100):
elm = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", liebiao1[i])[0] #获取当前工程中名字为列表liebiao1中第i个元素的文本框
elm.text = liebiao5[i] #将当前工程中名字为列表liebiao1中第i个元素的文本框的内容改为列表liebiao5中第i个元素
if os.path.exists(temp_filename): #删除临时PDF
os.remove(temp_filename)
arcpy.mapping.ExportToPDF(mxd, temp_filename) #生成临时PDF,这个PDF只有一页
finalPdf.appendPages(temp_filename) #将临时PDF追加到“chuti3.pdf”中
finalPdf.saveAndClose() #保存“chuti3.pdf”
if os.path.exists(temp_filename): #删除临时PDF
os.remove(temp_filename)
del mxd