作品展示
背景需求:
安全主任再次催交台账
一分园老师发的是链接版——这是我原来制作的在线共享填写“腾讯文档”。但是感觉手机竖版填写起来不方便,(表格是横版的,要向右滑动点击格子,填起来容易错行),所以我推荐使用问卷星填写了。
腾讯文档里面是选择按钮填入信息,也是所有数据依次填写,一条条向下排列,(不是按照20条20条分开)
需求:
1、“一分院电子屏台账”的腾讯文档的最终权限在我账户里,所以我负责修改样式。
2、我也想试试把腾讯文档的内容做成word20页的样式,并且右上角是“一分园)
设计步骤
登陆腾讯文档电脑版,下载”一分园
EXCEL样式
1、一共有7列内容(序号、编号1、编号2、时间、操作内容、进出人员、审核领导
2、序号很多,但是只有46条填写了。实际46行,不是139行
WORD模板
代码解析:
1、读取B:G列内容(如果是空格,就跳过)
2、计算实际几条、氛围6个一组
3、凑满60条,3页
4、重新制作需要填入的内容,特别是datetime.datetime()的转换,是靠AI对话大师获得的
5、确定一共有几页(20条一页)
6、从word表格里,替换园区名称
全部代码
'''
电子屏台账2024年3月,docx,每页20条(02电子屏幕台账(一分圆 腾讯文档)
作者:AI对话大师
时间:2024年4月7日13:15
'''
print('----1、读取EXCEL内容并合并成关键列表------')
month=int(input('几月?\n'))
garden=input('园区\n')
import os
import pandas as pd
import datetime
from docx import Document
folder_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\电子屏每月'
file_name = '(每日 一分园)XXXX幼儿园电子屏、播控系统日常管理台账(3月).xlsx'
file_path = os.path.join(folder_path, file_name)
# 按行读取
df = pd.read_excel(file_path)
# 按行读取B到G列的数据,不包括第1、2行(0和1) 0开始,就包含了电子屏一列,1-7B:G,就默认不读取00格里面的大标题
rows = df.iloc[1:, 1:7].values.tolist()
all_data = []
for row in rows:
row_data = [cell for cell in row if not pd.isnull(cell)and cell != '(跳过)']
all_data.extend(row_data)
print(all_data)
print(len(all_data))
# # 276/6=46行
print('----1、读取EXCEL内容并合并成关键列表------')
import pandas as pd
# df = pd.read_excel(file_path)
# num_rows = df.shape[0]
# print("行数:", num_rows)
# #实际是140行,但是和面大量是空格,所以还是要以提取行数除以6,测算行数
num_rows=int(len(all_data)/6)
print(num_rows)
# 46行
# 每行有几个内容
h=int(len(all_data)/(num_rows))
print(h)
# # 拆分成6个一组
nested_lists = [all_data[i:i+h] for i in range(0, len(all_data), h)]
print(nested_lists)
print(len(nested_lists))
# # 46
# 判断是否能够凑满20行,凑不满,补空
for z in range(20,220,20):
if z <= len(nested_lists)<z+20:
print(f"{len(nested_lists)} 在范围 {z}-{z+20} 内")
# 46 在范围 40-60 内
# 补多少的空格
kong=z+20-len(nested_lists)
print(kong)
# 14
# 有几页
Y=int((z+20)/20)
# 一个列表里面有6个空
w = [''] * h
# 需要14个这种6空的嵌套列表
v = [w] * kong
print(v)
# 把实际的填写内容+补充的空格,凑满20的倍数页
nested_lists=nested_lists+v
print(nested_lists)
print(len(nested_lists))
# 60
import datetime
# 拆分合并每个格子的内容
# [40263700000062, 'TY2013000005', datetime.datetime(2024, 3, 25, 7, 30), '新建页面', '钱XX', '管XX']
new=[]
for n in range(len(nested_lists)): # 66行
# 如果读取的第一个内容为空
if nested_lists[n][1]=='':
for g in range(h+1):
# 6个内容+1个序号
new.append('')
else:
# 添加序号不用加0
new.append(str(n+1))
# # 电子屏ID
new.append(str(nested_lists[n][0]))
# 资产编号
new.append(nested_lists[n][1])
# # 时间 (日期+时间
dt=nested_lists[n][2]
# dt = datetime.datetime(2024, 3, 14, 15, 30)
# 将datetime对象转换为字符串,并使用replace()方法替换Unicode字符
formatted_dt = dt.strftime("%Y{0}%m{1}%d{2}%H:%M").format('年', '月', '日')
# print(formatted_dt)
new.append(formatted_dt)
# 操作内容
new.append(nested_lists[n][3])
# 进出人员 (负责人)
new.append(nested_lists[n][4])
# 审核领导(园所管理主任)
new.append(nested_lists[n][5])
print(new)
print(len(new))
# # 420 /7/60=3页
print('----2、读取docx模板的数量------')
# 读取word的行列数
from docx import Document
doc_name = '电子屏台账模板.docx'
doc_path = os.path.join(folder_path, doc_name)
# 打开文档
doc = Document(doc_path)
# 获取第一个表格
table = doc.tables[0]
# 获取表格的行数和列数
num_rows = len(table.rows)
num_cols = len(table.columns)
print("行数:", num_rows)
# 22
print("列数:", num_cols)
# 7
# 每页格子的坐标
bg=[]
for a in range(2,22):
for b in range(7):
bg.append('{}{}'.format('%02d'%a,'%02d'%b))
print(bg)
print(len(bg))
# 140
# 拆分成4页每页20个个一组
c=int(len(new)/Y)
content_lists = [new[i:i+c] for i in range(0, len(new), c)]
print(content_lists)
print(len(content_lists))
# 4 拆20行内容一组,一共4个嵌套列表
# 列表new内容写入docx模板,第一页写入20行*7的内容
import os,time
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
from docx2pdf import convert
from PyPDF2 import PdfMerger
## 宋体四号
ziti = '宋体'
size = 14
imagePath = folder_path+r'\零时Word'
if not os.path.exists(imagePath):
os.makedirs(imagePath)
for n in range(len(content_lists)):
doc = Document(doc_path)
# for b in range(0):
table = doc.tables[0]
for t in range(len(bg)):
pp, qq, k = int(bg[t][0:2]), int(bg[t][2:4]), content_lists[n][t]
run = table.cell(pp, qq).paragraphs[0].add_run(str(k))
run.font.name = ziti
run.font.size = Pt(size)
run.bold = False
run.font.color.rgb = RGBColor(0, 0, 0)
r = run._element
r.rPr.rFonts.set(qn('w:eastAsia'), ziti)
table.cell(pp, qq).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
doc.save(imagePath+fr'\{n:02d}.docx')
time.sleep(2)
print('-----3、创建一个带页码的docx,合并word模板------')
from docx import Document
from docx.enum.section import WD_SECTION_START
import os
from docx.shared import Cm
# # 创建一个带页码的空Document对象,并把页眉页脚边距改小
source_dir = imagePath # 文件夹路径
combined_doc = Document(folder_path+r'\页码.docx')
# 读取“整理”里面的docx的内容
docx_files = []
for file_name in os.listdir(source_dir):
if file_name.endswith(".docx"):
docx_files.append(os.path.join(source_dir, file_name))
for file in docx_files:
doc = Document(file)
for element in doc.element.body:
combined_doc.element.body.append(element)
output_file = folder_path + fr'\2024年{month}月(一分园)电子屏台账.docx' # 输出文件路径
combined_doc.save(output_file)
print('-----4、把“合并docx"的第一段回车删除。(页码模板自带)---')
doc = Document(output_file)
# 删除第1个段落(都只有一个回车)
for i in [0,1]:
dell_paragraph = doc.paragraphs[i]
doc._element.body.remove(dell_paragraph._element)
# 保存文档
doc.save(output_file)
time.sleep(2)
print('-----5、替换园区---')
import win32com.client as win32
# 创建Word应用程序对象
word_app = win32.gencache.EnsureDispatch("Word.Application")
# 打开Word文档
doc = word_app.Documents.Open(output_file)
# 创建Find对象
find_object = doc.Content.Find
# 设置查找和替换参数
find_object.Text = "园区"
find_object.Replacement.Text = garden
find_object.Forward = True
find_object.Wrap = 1
find_object.Format = False
find_object.MatchCase = False
find_object.MatchWholeWord = False
find_object.MatchWildcards = False
find_object.MatchSoundsLike = False
find_object.MatchAllWordForms = False
# 执行查找和替换
find_object.Execute(Replace=2)
# 保存文档
doc.SaveAs(output_file)
# 关闭文档和应用程序
doc.Close()
word_app.Quit()
time.sleep(2)
# 删除word临时文件夹
import shutil
shutil.rmtree(imagePath)