【教学类-52-14】20240925动物数独(N宫格通用版)1图、2图、6图、有答案、无答案 组合版18套

news2024/9/27 5:41:24

背景需求:

制作了3-5宫格(1、2、6图)样式18组,它们用的都是(1、2、6图)的word模板,只是宫格数量不同,图片插入大小不同,是否可以做一个通用代码?

【教学类-52-11】20240919动物数独(4宫格)1图、2图、6图、有答案、无答案 组合版18套-CSDN博客文章浏览阅读1.7k次,点赞57次,收藏16次。【教学类-52-11】20240919动物数独(4宫格)1图、2图、6图、有答案、无答案 组合版18套https://blog.csdn.net/reasonsummer/article/details/142442572【教学类-52-13】20240924动物数独(5宫格)1图、2图、6图、有答案、无答案 组合版18套-CSDN博客文章浏览阅读636次,点赞19次,收藏4次。【教学类-52-13】20240924动物数独(5宫格)1图、2图、6图、有答案、无答案 组合版18套https://blog.csdn.net/reasonsummer/article/details/142497906【教学类-52-12】20240923动物数独(6宫格)1图、2图、6图、有答案、无答案 组合版18套-CSDN博客文章浏览阅读466次。【教学类-52-12】20240923动物数独(6宫格)1图、2图、6图、有答案、无答案 组合版18套https://blog.csdn.net/reasonsummer/article/details/142468814

通过修改名称,修改代码,实现这个需求。

0、材料准备

1、图片:

原来的四种动物是他人的(兔、猫、猴、猪)

为了做6宫格我又从网上下载了两个风格近似的图片——熊猫和狮子。

这次我想最多10宫格,所以需要10个动物,网上看看也配不齐同一个风格的。

为了避免版权问题,加上需要同样大小、同样风格的动物头像,我决定用通义万相生成的AI动物图片。

找到一套8月2日下载的彩色动物头像正面

从中挑选一些好看的头像(用ps把动物头像放大撑满画布,图案变大)选择了18种,大于10种。

为了了解生成一套要多少时间,添加了起始时间和终止时间

(星火讯飞生成)

from datetime import datetime

# 记录程序开始时间
start_time = datetime.now()

# 在这里编写你的程序代码

# 记录程序结束时间
end_time = datetime.now()

# 计算程序运行时间
elapsed_time = end_time - start_time

# 打印程序运行时间
print("程序运行时间:", elapsed_time)

2、制作3-10宫格的模版(制作底图)

 3宫格基础模版

 4宫格基础模版

 5宫格基础模版

6宫格基础模版

7宫格基础模版

8宫格基础模版

9宫格基础模版

10宫格基础模版

3、关卡图:

1图关卡、2图关卡、6图关卡

代码解析:

通用代码中的N*N小图片大小需要预先设置好

代码展示


# -*- coding:utf-8 -*-

'''
制作动物/脸谱数独N宫格通用版(3-10的黏贴关卡 A4 1图2图6图的所有组合 )
1.无答案:9种3:3,两两组合
2.有答案:27种 3:3:3,三三组合(实际需要其中9种)
作者:AI对话大师,阿夏
时间:2024年9月24日
'''


print('-----第一板块、动物操作卡(大图片卡一页1图、1页2图 一页6图)-------')

    


# print('----1、读取行列-------')
import os,time
from docx import Document
from docx.shared import Cm
from docx2pdf import convert
from PyPDF2 import PdfMerger
import shutil
from datetime import datetime


num=1
# int(input('生成几份\n'))
# 制作"单元格"# 几宫格
hsall=int(input('几宫格?(3-10)\n'))
# 程序开始的时间:

start_time = datetime.now()


# int(input('请输入4或9\n'))
hs=hsall

path=fr'C:\Users\jg2yXRZ\OneDrive\桌面\动物数独N宫格'

# 以下是1图、2图、6图的插入大小
psize=[19.6,14.1,9.39]
pg=[1,2,6]
gzs=[1,2,2]

# 以下是3=10宫格word里面的图片大小尺寸
# 3=6.4 、4=4.8、5=4.2、6=3
gzsize=[6.4,4.8,3.84,3.2]
# 3=10宫格宫格
gzsgg=list(range(3, 11))


for pt in range(len(pg)):
    # # 新建一个”装N份word和PDF“的临时文件夹
    imagePath=path+r'\\零时Word'
    os.makedirs(imagePath,exist_ok=True)  # 若图片文件夹不存在就创建
    
    imagePathpaste=path+r'\\05操作卡pdf'
    os.makedirs(imagePathpaste,exist_ok=True) 

    doc = Document(path +fr'\动物数独({pg[pt]}图关卡).docx')

    # 获取文档中的所有表格
    tables = doc.tables

    # 选择你需要读取的表格(在这种情况下是第1张表格)
    target_table = tables[0]

    # 获取所选表格的行数和列数
    num_rows = len(target_table.rows)
    num_columns = len(target_table.columns)

    print("行数:", num_rows)
    # 3
    print("列数:", num_columns)
    # # 2 

    print('----2、读取图片-------')

    import os

    # 指定文件夹路径
    folder_path = path + r'\02动物图片'

    pic_list = [os.path.join(folder_path, file_name) for file_name in os.listdir(folder_path)]
    pic_list=pic_list[:hs]*hs
    print(pic_list)
    print(len(pic_list))
    
    print(pic_list)
    print(len(pic_list))
    
    groups = [pic_list[i:i + int(pg[pt])] for i in range(0, len(pic_list), int(pg[pt]))]
    

    # # # print('----3、黏贴图片卡,一页1图、1页2图 一页6图-------')

   
        # 处理每一组图片
    for group_index, group in enumerate(groups):
        # 创建新的Word文档
        doc = Document(path + fr'\动物数独({pg[pt]}图关卡).docx')
        # print(group)
        
        # 遍历每个单元格,并插入图片
        for cell_index, image_file in enumerate(group):
            # 计算图片长宽(单位:厘米)
            cc=float(psize[pt])
            # 插入图片到单元格
            table = doc.tables[0]
            cell = table.cell(int(cell_index / int(gzs[pt])), cell_index % int(gzs[pt]))
    #         # 如果第一行有4个格子,两个数字都写4
            cell_paragraph = cell.paragraphs[0]
            cell_paragraph.clear()
            run = cell_paragraph.add_run()
            
            run.add_picture(os.path.join(image_file), width=Cm(cc), height=Cm(cc))
            cell_paragraph.alignment = 1  # 设置单元格中的文本居中
      


        # 保存修改后的.docx文件
        doc.save(imagePath + fr'\{group_index + 1:02d}页.docx')
        # docx 文件另存为PDF文件
        inputFile = imagePath + fr'\{group_index + 1:02d}页.docx'  # 要转换的文件:已存在
        outputFile = imagePath + fr'\{group_index + 1:02d}页.pdf'  # 要生成的文件:不存在
        convert(inputFile, outputFile)
        time.sleep(hs)

    # 合并PDF文件
    pdf_lst = [f for f in os.listdir(imagePath) if f.endswith('.pdf')]
    pdf_lst = [os.path.join(imagePath, filename) for filename in pdf_lst]
    pdf_lst.sort()
    file_merger = PdfMerger()
    for pdf in pdf_lst:
        file_merger.append(pdf)

    file_merger.write(imagePathpaste + fr"\03 {pg[pt]:02}图操作卡.pdf")
    file_merger.close()
    # 删除零时文件夹
    shutil.rmtree(imagePath)

print('-----第二板块、动物任务卡和答案卡一套,只要JPG-------')



import random
from win32com.client import constants, gencache
from win32com.client.gencache import EnsureDispatch
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 docx.enum.text import WD_ALIGN_PARAGRAPH


import docxtpl
import pandas as pd
from docx2pdf import convert

from docx.oxml.ns import nsdecls
from docx.oxml import parse_xml
import copy





# kk=int(input('空格数量,输入5,就是50%,就是空一半)\n'))

print('------3-1、如果正好想生成1空、2空、3空、4空的数字,需要测算百分比的具体数字------')

n=hsall
g=n*n

a=[]
for i in range(1,101):
    # 因为有100,所以三位数
    
    print(f'{n}宫格,难度{i:03d},抽取{i:03d}%:实际有{int(g*i/100):03d}空,已有图案{g-int(g*i/100):03d}')
    a.append(f'{n}宫格,难度{i:03d},抽取{i:03d}%:实际有{int(g*i/100):03d}空,已有图案{g-int(g*i/100):03d}')
print(a)
print(len(a))
# # 用冒号分割,如果0空,加入,

# 创建一个空列表用于存储匹配的元素
b = []

# 遍历原始列表
for element in a:
    # 如果找到匹配的元素,以":"为分隔符将字符串分割成两部分
    parts = element.split(":")
    # print(parts)
    # # 提取第一部分中包含的数字信息
    info = parts[1]
    b.append(info)
# 对列表b进行排序,并去除重复项
b = list(set(b))
b.sort(reverse=False)
print(b)

f=[]
for d in range(len(b)):
    for c in a:
        # print(c)
        # 读取一个就中断
        if c[-15:]==b[d]:
            f.append(c)
            break
f.pop(0)
# 删除['6宫格,难度01,抽取1%:实际有00空,已有图案14', 
# f.pop(-1)
# # 删除'6宫格,难度100,抽取100%:实际有14空,已有图案00'
print(f)
# ['6宫格,难度007,抽取007%:实际有001空,已有图案015', '6宫格,难度013,抽取013%:实际有002空,已有图案014', '6宫格,难度019,抽取019%:实际有003空,已有图案013', '6宫格,难度025,抽取025%:实际有004空
# ,已有图案012', '6宫格,难度032,抽取032%:实际有005空,已有图案011', '6宫格,难度038,抽取038%:实际有004空,已有图案010', '6宫格,难度044,抽取044%:实际有007空,已有图案009', '6宫格,难度050,抽取050%:实际有008空,已有图案008', '6宫格,难度057,抽取057%:实际有009空,已有图案007', '6宫格,难度043,抽取043%:实际有010空,已有图案004', '6宫格,难度049,抽取049%:实际有011空,已有图案005', '6宫格,
# 难度075,抽取075%:实际有012空,已有图案004', '6宫格,难度082,抽取082%:实际有013空,已有图案003', '6宫格,难度088,抽取088%:实际有014空,已有图案002', '6宫格,难度094,抽取094%:实际有015空,已有图案
# 001']
print(len(f))
# 15
# 难度有15关

# 提取百分数
g=[]
w=[]
for p in f:
    g.append(int(p[12:15]))    # 提取第4-7个数字=百分比数字
    w.append(int(p[20:23]))    # 提取空格数量
print(g)
# [7, 13, 19, 25, 32, 38, 44, 50, 57, 43, 49, 75, 82, 88, 94]
print(len(g))
# 15关
print(w)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
print(len(w))
# 34

print('------2、制作6宫格随机数字------')

# 制作"单元格"# 几宫格
for kk in range(len(g)):
# hs=int(input('请输入宫格数量(3,5.4,7,8,)\n'))

#  因为有3-9的不同word模板,所以有不同的套数和字体大小
    ll=['3','5','6','7','8','10',] # 如果输入345
    mm=['53','32','32','32','32','32',]# 3对应的套数是4*3套
    nn=['36','36','36','24','24','22']# 3对应的写入单元格的数字大小36磅 
    
    # 因为有3-9的不同word模板,所以有不同的套数和字体大小
    ll=['{}'.format(hs)] # 如果输入345
    mm=['11']# 3对应的套数是4*3套
    nn=['36']# 3对应的写入单元格的数字大小34磅 
    for r in range(len(ll)):
        if hs ==int(ll[r]):
            # 底边几套.底边看有2份
            db=int(mm[r][0])
            # int(input('底边几套? 3\n'))
            # 侧边几套 侧边看也是2份
            print(db )        
            cb=int(mm[r][1])
            # int(input('侧边几套? 2\n'))
            print(cb)
            size=int(nn[r])
            print(size)        # 写入单元格数字的大小(撑满格子)

    # path=fr'C:\Users\jg2yXRZ\OneDrive\桌面\动物数独{hs}宫格'
    # 新建一个”装N份word和PDF“的临时文件夹
    imagePath=path+r'\\零时Word'
    os.makedirs(imagePath,exist_ok=True) 

   

    imagePatha=path+r'\06答案卡'
    imagePathq=path+r'\07任务卡'
    os.makedirs(imagePatha,exist_ok=True)
    os.makedirs(imagePathq,exist_ok=True)

    # 计算不同模板中的单元格坐标,放在bg里
    # 棋盘格子数量,
    # 如果长方形:底边3*侧边2,3*2=4套 ,就是10*10宫格,底边格子数量就是10*3=30,侧边格子数量就是10*2=20,
    # if db==cb:

    db_size = hs*db
    cb_size=  hs*cb
    print('{}宫格排列底{}侧{}共{}套,底边格子数{}'.format(hs,db,cb,db*cb,db_size ))
    print('{}宫格排列底{}侧{}共{}套,侧边格子数{}'.format(hs,db,cb,db*cb,cb_size ))

    # 确定每个宫格的左上角坐标 00 04 40  44 中间没有分栏的空格了,所以hs不用+1
    bgszm=[]
    for a in range(0,cb_size,hs):    # 0-11每隔4,写一个坐标  侧边y
        for b in range(0,db_size,hs):  # 0-11每隔4,写一个坐标  侧边x
            bgszm.append('{}{}'.format('%02d'%a,'%02d'%b))
    print(bgszm)
    # 10宫格排列底3侧2共4套,底边格子数30
    # 10宫格排列底3侧2共4套,侧边格子数20
    # 10宫格排列底3侧2共4套,侧边格子数20
    # ['0000', '0010', '0020', '1000', '1010', '1020']
        

    # 转为元祖
    start_coordinates = [(int(s[0:2]), int(s[2:4])) for s in bgszm]
    cell_coordinates = []

    # 推算每个起始格子后面的单元格数字
    for start_coord in start_coordinates:
        i, j = start_coord
        subgrid_coordinates = []
        for x in range(hs):
            for y in range(hs):
                subgrid_coordinates.append((i + x, j + y))
        cell_coordinates.append(subgrid_coordinates)

    # 打印结果(元祖样式)
    bg=[]
    for coordinates in cell_coordinates:
        # print(coordinates)     # [(4, 8), (4, 9), (4, 10), (5, 8), (5, 9), (5, 10), (4, 8), (4, 9), (4, 10)]
        for c in  coordinates:
            print(c)        # 元组 (1, 2) 样式
            s = ''.join(str(num).zfill(2) for num in c)   # zfill将元组 (1, 2) 转换为字符串 '0102' 特别是(5,10)这种必须转成2个数字0510
            print(str(s))        #  '12'
            bg.append(s)  #  '0102'
    print(bg)


    # 生成PDf
    P=[] 
    for z in range(num):  
        P.clear()
        #    制作4份数据
        for j in range(db*cb):    #  3宫格,4*3=12套
        
            def generate_sudoku_board():
                # 创建一个9x9的二维列表,表示数独棋盘
                board = [[0] * hs for _ in range(hs)]

                # 递归函数,用于填充数独棋盘的每个单元格
                def filling_board(row, col):
                    # 检查是否填充完成整个数独棋盘
                    if row == hs:
                        return True
                    
                    # 计算下一个单元格的行和列索引
                    next_row = row if col < hs-1 else row + 1
                    next_col = (col + 1) % hs

                    import math

                    r = int(math.sqrt(hs))
                    print(r)

                    # 获取当前单元格在小九宫格中的索引
                    box_row = row // r
                    box_col = col // r

                    # 随机生成1到9的数字
                    numbers = random.sample(range(1, hs+1), hs)
                    
                    for num in numbers:
                    
                    # 检查行、列、小九宫格是否已经存在相同的数字
                        if hs==4 or hs==9:
                            if num not in board[row] and all(board[i][col] != num for i in range(hs)) and all(num != board[i][j] for i in range(box_row*r, box_row*r+r) for j in range(box_col*r, box_col*r+r)):
                                board[row][col] = num

                                # 递归填充下一个单元格
                                if filling_board(next_row, next_col):
                                    return True

                                # 回溯,将当前单元格重置为0
                                board[row][col] = 0

                        else:               # 检查行、列、小九宫格是否已经存在相同的数字
                            if num not in board[row] and all(board[i][col] != num for i in range(hs)) and all(num != board[i][j] for i in range(box_row, box_row) for j in range(box_col, box_col)):
                                board[row][col] = num

                                # 递归填充下一个单元格
                                if filling_board(next_row, next_col):
                                    return True

                                # 回溯,将当前单元格重置为0
                                board[row][col] = 0

                    return False

                # 填充数独棋盘
                filling_board(0, 0)
                return board

            # 第一种是出现全部数字,也就是出现全部图案
            board1 = generate_sudoku_board()

            # 定义类型1
            def create_board1():                
                return board1

            # 定义类型2
            def create_board2(): # level数字越大代表游戏难度越大
                """
                生成一个随机的数独棋盘,空白格少
                """
                global board1  # 全局变量
               
                # 第二种定量出现空白格子
                board2 =  copy.deepcopy(board1)
                ggg=int(g[kk])
                blanks = random.sample(range(hs*hs), int(float(hs*hs*ggg)/100))  # 16*97/100=15.52是浮点数,然后再转成整数
                # blanks = 0
                for i in blanks:
                    row = i // hs
                    col = i % hs
                    board2[row][col] = 0

                        
                    # if random.randint(0, hs) < level:
                    #     board1[row][col] = 0
                return board2
            # 16个数字
            v1 = create_board1()    
            # 16-X个数字    
            v2 = create_board2()

            v=v1+v2
            print(v)
            # [[1, 4, 2, 3], [3, 2, 4, 1], [4, 1, 3, 2], [2, 3, 1, 4], [1, 4, 2, 3], [3, 2, 4, 1], [4, 1, 3, 2], [0, 3, 1, 4]]

            

            # 提取每个数字
            P = ['' if a2 == 0 else a2 for a1 in v for a2 in a1]
            print(P)
            print(len(P))
            # [1, 4, 2, 3, 3, 2, 4, 1, 4, 1, 3, 2, 2, 3, 1, 4, 1, 4, 2, 3, 3, 2, 4, 1, 4, 1, 3, 2, '', 3, 1, 4]
            
            half_len = int(len(P) // 2)
            Q = [P[i:i+half_len] for i in range(0, len(P), half_len)]
            print(Q)
            # [[1, 4, 2, 3, 3, 2, 4, 1, 4, 1, 3, 2, 2, 3, 1, ],[4, 1, 4, 2, 3, 3, 2, 4, 1, 4, 1, 3, 2, '', 3, 1, 4]]
            

            time.sleep(hs)          


                   
        print('------答案卡和题目卡------')  
        
        title=['答案卡','任务卡']

        imagePath1=path+r'\答案卡1'
        imagePath2=path+r'\任务卡1'
        os.makedirs(imagePath1,exist_ok=True)
        os.makedirs(imagePath2,exist_ok=True)

       
               


        ti=[path+r'\答案卡1',path+r'\任务卡1']       
        
        for tt in range(len(Q)):          
            doc = Document(path+fr'\动物数独(横板{hs}宫格).docx')  
            # 获取第一个表格,写难度用的
            table = doc.tables[0]
            for b1 in range(0,1):
                # 在'00'单元格中插入文本
                cell_00 = table.cell(0, b1)
                cell_00_paragraph = cell_00.paragraphs[0]
                cell_00_paragraph.text =f"动物数独 {hs}*{hs}  宫格 第 {kk+1} 关 {title[tt]}"
                cell_00_paragraph.style.font.bold = True
                cell_00_paragraph.style.font.size = Pt(24)
                cell_00_paragraph.style.font.name = "黑体"
                cell_00_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

            #    
            table = doc.tables[1]          # 表0,表2 写标题用的
            # 标题写入3、5单元格  
            for t in range(0,len(bg)):             # 0-5是最下面一行,用来写关卡数字
                pp=int(bg[t][0:2])     # 
                qq=int(bg[t][2:4])
                k=str(Q[tt][t])              # 提取list图案列表里面每个图形  t=索引数字
                print(pp,qq,k)

                # 图案符号的字体、大小参数
                run=table.cell(pp,qq).paragraphs[0].add_run(k)    # 在单元格0,0(第1行第1列)输入第0个图图案
                run.font.name = '黑体'#输入时默认华文彩云字体
                # run.font.size = Pt(44)  #输入字体大小默认30号 换行(一页一份大卡片
                run.font.size = Pt(size) #是否加粗
                # run.font.color.rgb = RGBColor(150,150,150) #数字小,颜色深0-255
                run.font.color.rgb = RGBColor(0,0,0) #数字小,颜色深0-255
                run.bold=True
                # paragraph.paragraph_format.line_spacing = Pt(180) #数字段间距
            
                r = run._element
                r.rPr.rFonts.set(qn('w:eastAsia'), '黑体')#将输入语句中的中文部分字体变为华文行楷
                table.cell(pp,qq).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER#居中  

            doc.save(ti[tt]+fr'\{z+1:02d}.docx')
            time.sleep(hs)

        
            print('------4、每张word转为pdf----')      
            from docx import Document
            from docx.shared import Cm

            # 读取四张卡通动物的文件名
            animal_path = path+r'\02动物图片'  # 替换为实际的文件夹路径
            # 获取文件夹中所有文件的完整路径
            file_paths = [os.path.join(animal_path, file_name) for file_name in os.listdir(animal_path)]
            print(file_paths)

        
            doc = Document(ti[tt]+fr'\{z+1:02d}.docx')
           

            # 获取所有表格
            tables = doc.tables

            # 遍历每个表格
            for table in tables:
                # 遍历表格的行
                for i, row in enumerate(table.rows):
                    # 遍历行的单元格
                    for j, cell in enumerate(row.cells):
                        # 读取单元格的文本值
                        cell_text = cell.text

                        for x in range(0,hs):
                        # 判断单元格的值是否为1
                            if cell_text == f'{x+1}':
                                # 删除原来的文本
                                cell.text = ''
                                # 插入图片
                                run = cell.paragraphs[0].add_run()
                                # 4.8格子

                            
                                for n in range(len(gzsgg)):
                                    if hs==gzsgg[n]:
                                        run.add_picture(file_paths[x], width=Cm(gzsize[n]), height=Cm(gzsize[n]))
                                    # 设置图片对齐方式为居中
                                        run.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                                        # 设置单元格的水平和垂直对齐方式为居中
                                        cell.vertical_alignment = WD_ALIGN_PARAGRAPH.CENTER
                                        cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
                            

            # 保存修改后的文档
            doc.save(ti[tt]+fr'\{z+1:02d}.docx')
            time.sleep(hs)

            # # 关闭Word文档
            # doc.close()
            
            from docx2pdf import convert
            # docx 文件另存为PDF文件
            inputFile = ti[tt]+fr'\{z+1:02d}.docx'
            outputFile =ti[tt]+fr'\{z+1:02d}.pdf'
            # 先创建 不存在的 文件A
            f1 = open(outputFile, 'w')
            f1.close()
            # 再转换往PDF中写入内容
            convert(inputFile, outputFile)
            time.sleep(hs)       
            
        print('----------更改pdf新名字------------')                    
        # 两个pdf
        import os
        from PyPDF2 import PdfFileReader, PdfFileWriter
        
        tii=[path+r'\06答案卡',path+r'\07任务卡']

        
        for t3 in range(len(tii)):
            pdf_lst = [f for f in os.listdir(ti[t3]) if f.endswith('.pdf')]

            pdf_path = os.path.join(ti[t3], pdf_lst[0]) 
            print(pdf_path)         
            # 源头文件名C:\Users\jg2yXRZ\OneDrive\桌面\动物数独6宫格\答案卡1\01.pdf    
            new_file_name = f"{title[t3]} 动物拼图{hs}宫格 难度{kk+1:02d} 空{int(w[kk]):03d}格({db}乘{cb}等于{num}份{db*cb}张).pdf"  
            

            # 重命名并移动文件到imagePatha文件夹下
            output_path = os.path.join(tii[t3], new_file_name)
            print(output_path)
            # 目标文件名C:\Users\jg2yXRZ\OneDrive\桌面\动物数独6宫格\答案卡\答案卡 动物拼图6宫格 难度01 空001格(1乘1等于1份1张).pdf
            os.rename(pdf_path, output_path)            # 源文件名,目标文件名
            time.sleep(hs)   
            
            shutil.rmtree(ti[t3]) #递归删除文件夹,即:删除非空文件夹
            time.sleep(hs)    # 防止转换时报错,预留生成时间


print('----------第4步:把都有16管PDF关卡变png------------')

#coding=utf-8
from win32com.client import Dispatch
import os
import re
import fitz

wdFormatPDF = 17 #转换的类型
zoom_x=2 #尺寸大小,越大图片越清晰 5超大,这里改成2
zoom_y=2 #尺寸大小,越大图片越清晰,长宽保持一致
rotation_angle=0#旋转的角度,0为不旋转


li=[path+r'\06答案卡',path+r'\07任务卡']
for l in li:
    for root, dirs, files in os.walk(l):
        for file in files:
            if re.search('\.pdf$', file):
                filename = os.path.abspath(root + "\\" + file)
                print(filename)
                # 打开PDF文件
                pdf = fitz.open(filename)
                # 逐页读取PDF
                for pg in range(0, pdf.pageCount):
                    page = pdf[pg]
                    # 设置缩放和旋转系数
                    trans = fitz.Matrix(zoom_x, zoom_y).preRotate(rotation_angle)
                    pm = page.getPixmap(matrix=trans, alpha=True)
                    # 开始写图像
                    pm.writePNG(filename.replace('.pdf', '') + str(pg+1) + ".png")
                pdf.close()

    # 删除生成文件PDF  
    for parent, dirnames, filenames in os.walk(l):
        for fn in filenames:
            if fn.lower().endswith('.pdf'):
                os.remove(os.path.join(parent, fn))




print('-----第三板块、把动物任务卡和答案卡一套分别做成1页1份,1页2份,1页6份的pdf-------')


psize=[9.39,9.39,14.1,14.1,19.6,19.6]
# ,
pg=[6,6,2,2,1,1]
# ,'2',
gzs=[2,2,2,2,1,1]
# '1','2',
nh=[1,2,1,2,1,2]


# print('----1、读取行列-------')
from docx import Document
from docx.shared import Cm
import os

for x in range(len(pg)):    # # 新建一个”装N份word和PDF“的临时文件夹    

    imagePath11=path+r'\08答案卡pdf'
    imagePath22=path+r'\09任务卡pdf'
    os.makedirs(imagePath11,exist_ok=True)
    os.makedirs(imagePath22,exist_ok=True)

    tiii=[path+r'\08答案卡pdf',path+r'\09任务卡pdf',path+r'\08答案卡pdf',path+r'\09任务卡pdf',path+r'\08答案卡pdf',path+r'\09任务卡pdf']
    
    tii=[path+r'\06答案卡',path+r'\07任务卡',path+r'\06答案卡',path+r'\07任务卡',path+r'\06答案卡',path+r'\07任务卡']
    title=['答案卡','任务卡','答案卡','任务卡','答案卡','任务卡']
    # for x in range(len(tiii)):
    imagePath=path+r'\\零时Word'
    os.makedirs(imagePath,exist_ok=True)  # 若图片文件夹不存在就创建
    # 打开.docx文件
    doc = Document(path +fr'\动物数独({pg[x]}图关卡).docx')
    # 获取文档中的所有表格
    tables = doc.tables[0]

    import os           
#       
    file_paths = [os.path.join(tii[x], file) for file in os.listdir(tii[x])]

    # file_paths = [os.path.join(root, file) for root, dirs, files in os.walk(tii[x]) for file in files]      

    pic_list_six = [file_paths[i:i+int(pg[x])] for i in range(0, len(file_paths), int(pg[x]))]
    print(pic_list_six)
    print(len(pic_list_six))

       
     

    # # # print('----3、黏贴图片卡,一页1图、1页2图 一页6图-------')


        # 处理每一组图片
    for group_index, group in enumerate(pic_list_six):
        # 创建新的Word文档
        doc = Document(path + fr'\动物数独({pg[x]}图关卡).docx')
        # print(group)
        
        # 遍历每个单元格,并插入图片
        for cell_index, image_file in enumerate(group):
            # 计算图片长宽(单位:厘米)
            cc=float(psize[x])
            # 插入图片到单元格
            table = doc.tables[0]
            cell = table.cell(int(cell_index /gzs[x]), cell_index % gzs[x])
    #         # 如果第一行有4个格子,两个数字都写4
            cell_paragraph = cell.paragraphs[0]
            cell_paragraph.clear()
            run = cell_paragraph.add_run()
            
            run.add_picture(os.path.join(image_file), width=Cm(cc), height=Cm(cc))
            cell_paragraph.alignment = 1  # 设置单元格中的文本居中
    


        # 保存修改后的.docx文件
        doc.save(imagePath + fr'\{group_index + 1:02d}页.docx')
        # docx 文件另存为PDF文件
        inputFile = imagePath + fr'\{group_index + 1:02d}页.docx'  # 要转换的文件:已存在
        outputFile = imagePath + fr'\{group_index + 1:02d}页.pdf'  # 要生成的文件:不存在
        convert(inputFile, outputFile)
        time.sleep(hs+2)

    pdf_lst = [f for f in os.listdir(imagePath) if f.endswith('.pdf')]
    pdf_lst = [os.path.join(imagePath, filename) for filename in pdf_lst]
    pdf_lst.sort()
    file_merger = PdfMerger()
    for pdf in pdf_lst:
        print(pdf)
        file_merger.append(pdf)
    # file_merger.write("C:/Users/jg2yXRZ/OneDrive/桌面/描字帖/(打印合集)大班A整页描字帖2乘5加表格-4名字-({}人).pdf".format(num))
    file_merger.write(tiii[x]+ fr"\{nh[x]:02} {pg[x]:02}图{title[x]}.pdf")
    # 01 06图答题卡.pdf
     # 02 06图任务卡.pdf
    file_merger.close()
        # doc.Close()

    # # print('----------第5步:删除临时文件夹------------')    
    import shutil
    shutil.rmtree(imagePath) #递归删除文件夹,即:删除非空文件夹
  




print('-----第四板块、交叉合并有答案6套,无答案6套(1-1-1、1-1,1-2-2,1-2,2-1-1,2-1……----')
# 无答案:对09、05、文件夹(每份3个文件),进行交叉组合
import os
from PyPDF2 import PdfFileMerger

newgz=path+fr'\(打印)动物数独{hs}宫格18套'
os.makedirs(newgz,exist_ok=True)

address=[]
# '08答案卡pdf',
all=['09任务卡pdf','05操作卡pdf']
for y in all:
    new=path+fr'\{y}'   

    file_new = [os.path.join(new, f) for f in os.listdir(new)]
    # print(file_new)
    address.append(file_new)
print(address)

# 推导公式
combinations = [[x, y] for x in address[0] for y in address[1]]
print(combinations)

import PyPDF2

for files in combinations:
    print(files)
    pdf_merger = PyPDF2.PdfFileMerger()
    for file in files:
        pdf_merger.append(file)
    output_file = newgz+fr"\动物数独{hs}宫格(无答案) {files[0][-9:-4] } {files[1][-9:-4] }.pdf"
    pdf_merger.write(output_file)
    pdf_merger.close()

    
# 有答案:对08、09、05、文件夹(每份3个文件),进行交叉组合

import os
from PyPDF2 import PdfFileMerger

address=[]

all=['08答案卡pdf','09任务卡pdf','05操作卡pdf']
for y in all:
    new=path+fr'\{y}'   

    file_new = [os.path.join(new, f) for f in os.listdir(new)]
    # print(file_new)
    address.append(file_new)
print(address)
print(len(address))

# 推导公式
combinations = []

for i in address[0]:
    for j in address[1]:
        for k in address[2]:
            combinations.append([i, j, k])
print(combinations)
print(len(combinations))

import PyPDF2

for files in combinations:
    print(files)
    pdf_merger = PyPDF2.PdfFileMerger()
    for file in files:
        pdf_merger.append(file)
    output_file = newgz+fr"\动物数独{hs}宫格(有答案) {files[0][-9:-4] } {files[1][-9:-4]} {files[2][-9:-4]}.pdf"
    pdf_merger.write(output_file)
    pdf_merger.close()

# 删除答案卡任务卡样式不一致的

import os
import shutil


# 遍历文件夹下的所有文件
for file_name in os.listdir(newgz):
    # 检查文件是否为PDF格式
    if file_name.endswith(".pdf"):
        # 获取文件名前五个字符
               
        # 判断文件名是否符合条件
        if f"动物数独{hs}宫格(有答案)" in file_name:
            # 读取PDF文件内容
            # with open(os.path.join(folder_path, file_name), 'rb') as f:
            #     content = f.read()
            if  hs<10:   # 宫格数1-9,一位数
                # 检查第10和第15个字符是否相同
                if file_name[-15] == file_name[-21]:
                    # 保留符合条件的PDF文件
                    print(f"保留文件:{file_name}")
                else:
                    # 删除不符合条件的PDF文件
                    os.remove(os.path.join(newgz, file_name))
                    print(f"删除文件:{file_name}")
            

# # 分段测试用
# imagePath11=path+r'\08答案卡pdf'
# imagePath22=path+r'\09任务卡pdf'
# # imagePath=path+r'\零时Word'
# imagePatha=path+r'\06答案卡'
# imagePathq=path+r'\07任务卡'
# imagePathpaste=path+r'\05操作卡pdf'


shutil.rmtree(imagePath11) #递归删除文件夹,即:删除非空文件夹   
shutil.rmtree(imagePath22) #递归删除文件夹,即:删除非空文件夹
shutil.rmtree(imagePatha) #递归删除文件夹,即:删除非空文件夹
shutil.rmtree(imagePathq) #递归删除文件夹,即:删除非空文件
shutil.rmtree(imagePathpaste)


# 记录程序结束时间
end_time = datetime.now()

# 计算程序运行时间
elapsed_time = end_time - start_time

print(f"动物数独{hs}宫格程序开始时间:{start_time}")
print(f"动物数独{hs}宫格程序结束时间:{end_time}")

# 打印程序运行时间
print("程序运行时间:", elapsed_time)

3宫格大约16分钟

3宫格提取前3张图片

4宫格大约19分钟

5宫格大约19分钟

报错了,下次再补时长

6宫格大约19分钟

生成一次时间太长了,动不动就保存时间不够,总是报错,20240925生成3-6宫格,明天再做7-10宫格

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2164980.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#算法(16)—获取上升沿和下降沿信号

前言 我们在上位机软件开发的时候有时候需要抓取一个信号的上升沿或者下降沿,这时候就需要我们自己编写程序来实现抓取上升沿和下降沿的功能,详细内容如下: 一个信号从“无”到“有”,然后再从“有”到“无”,经历的过程如下:无-上升沿-有-下降沿-无,这样5个过程。 1…

基于微信小程序的电影院订票选座系统ssm(lw+演示+源码+运行)

摘 要 通过移动互联网这几年的发展&#xff0c;单独的开发某些APP已经到了日暮西山的地步&#xff0c;原因不在于单个的APP功能丰富与否&#xff0c;而是因为用户生态体系的问题。使用智能手机的用户经过多年的使用习惯&#xff0c;已经越来越不喜欢安装各种的APP&#xff0c;…

mysql 05 InnoDB数据页结构

01.数据页结构的快速浏览 02.记录在页中的存储 在页的7个组成部分中&#xff0c;我们自己存储的记录会按照我们指定的 行格式 存储到 User Records 部分。但是在一开始生成页的时候&#xff0c;其实并没有 User Records 这个部分&#xff0c;每当我们插入一条记录&#xff0c…

建立队列,插入队列,删除队列

代码&#xff1a; #include<iostream> using namespace std; template<class T> class sq_Queue {private:int mm;int front;int rear;int s;T *q; public:sq_Queue(int);void prt_sq_Queue();int flag_sq_Queue();void ins_sq_Queue(T);T del_sq_Queue(); }; tem…

【线程】自旋锁和读写锁

自旋锁 以前所讲的是挂起等待锁&#xff0c;申请锁成功继续执行&#xff0c;申请失败挂起等待 挂起等待和唤醒是需要时间的&#xff0c;有没有一种锁不会挂起等待呢&#xff1f;那就是自旋锁&#xff0c;申请锁失败它不会挂起&#xff0c;他会轮询&#xff0c;一直让我们的线…

如何给文件设置密级权限查看

一、使用文件加密软件&#xff1a; 选择专业的加密软件&#xff0c;如BitLocker&#xff08;Windows内置&#xff09; 对需要设置密级的文件进行加密&#xff0c;并设置访问密码。 这样&#xff0c;只有拥有正确密码的人才能查看或访问该文件。 二、第三方加密工具&#xff…

《Detection of Tea Leaf Blight in Low-Resolution UAV Remote Sensing Images》论文阅读

学习资料 论文题目&#xff1a;Detection of Tea Leaf Blight in Low-Resolution UAV Remote Sensing Images&#xff08;低分辨率UAV遥感图像中茶叶枯萎病的检测&#xff09;论文地址&#xff1a;https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber10345618 Abstr…

这个博览会不一般,丰收的背后故事多!

在金秋送爽、硕果累累的季节里&#xff0c;我们迎来了第七个中国农民丰收节&#xff0c;2024 年 9 月 24日&#xff0c;“中国农民丰收节毕节庆祝活动第三届毕节天麻博览会”在七星关区盛大开幕&#xff0c;一场办在农民心坎上的庆丰收活动精彩上演&#xff01;这是一场属于农民…

手把手教程 | 在 Azure OpenAI 服务上微调 4o 模型

兴奋起来——你现在可以使用 Azure OpenAI 服务微调 4o&#xff01; 我们很高兴地宣布在 Azure 上推出 4o 微调的公开预览版。在成功进行私人预览后&#xff0c;4o 现已可供我们所有的 Azure OpenAI 客户使用&#xff0c;在 Azure OpenAI 服务中提供无与伦比的定制和性能。 …

通信工程学习:什么是ODN光分配网络

ODN&#xff1a;光分配网络 ODN&#xff08;Optical Distribution Network&#xff0c;光分配网络&#xff09;是光接入网中的重要组成部分&#xff0c;它位于光线路终端&#xff08;OLT&#xff09;和光网络单元&#xff08;ONU&#xff09;/光网络终端&#xff08;ONT&#x…

itc保伦股份智慧高校整体解决方案推动教育强国、科技强国、人才强国建设!

党的二十大报告指出&#xff0c;要“统筹职业教育、高等教育、继续教育协同创新&#xff0c;推进职普融通、产教融合、科教融汇&#xff0c;优化职业教育类型定位”。itc积极响应高校人才培养相关政策要求&#xff0c;基于互联网、物联网、大数据、AI等技术&#xff0c;面向老师…

高性价比的电脑桌面记事本便签,好用便签助力工作效率

在快节奏的工作环境中&#xff0c;我们常常需要快速记录下重要的信息和任务。而一款好用的电脑桌面记事本便签工具&#xff0c;可以成为我们提高工作效率的得力助手。在这里&#xff0c;向大家介绍一款高性价比的电脑桌面记事本便签&#xff0c;好用便签&#xff0c;帮助大家更…

100个ChatGPT学术指令—助你高效完成文献综述撰写!

写文献综述是不是让你觉得头大&#xff1f;每次翻了半天资料&#xff0c;脑子还是一片空白&#xff0c;根本不知道从哪儿开始写&#xff1f; 别慌&#xff0c;其实有个简单的套路——用AI&#xff01;没错&#xff0c;只要掌握好提示词&#xff0c;AI能帮你快速理清思路、找到…

Linux系统备份Gitee等云git所有仓库与所有分支的数字资产

思路&#xff1a; 1. ssh 配置 2. reps.txt 列出所有仓库名 3. exp的自动化备份脚本 -- 环境安装&#xff1a; exp需要依赖安装的文件&#xff0c;所以先执行下(以ubuntu为例)&#xff1a; sudo apt-get install expect 操作步骤&#xff1a; ssh 配置 1. 添加公钥至 …

23. Lammps命令学习-8之read_dump

来源&#xff1a; “码农不会写诗”公众号 链接&#xff1a;Lammps命令学习-8之read_dump read_dump file … 从dump文件中读取原子信息以覆盖当前原子坐标以及原子速度和图像标志、时间步长和模拟盒尺寸等&#xff0c;以便可以从dump文件中的特定快照重新启动模拟。   https…

[笔记]某川电机变频器指标与参数

变频器是进行电机控制的一个参考源&#xff0c;所有这些电机厂商的产品中提及的功能模块&#xff0c;项点&#xff0c;都需要关注。 某些功能点&#xff0c;自定义的分类&#xff0c;都是一些可以用作参考和进一步扩展的一些基本的技术点。软硬件接口&#xff0c;可以在设计自…

2023国赛C题 蔬菜类商品的自动定价与补货决策(上)

2023国赛C题 蔬菜类商品的自动定价与补货决策&#xff08;上&#xff09; 符号说明&#xff1a; 问题1 问题1主要的代码和思路在上一篇文章“数学建模实战块速入门”中已经进行了较为详细的展示&#xff0c;在问题一种要求我们从蔬菜单品和品类两个维度去分析各自之间的关系。…

C# 面向对象基础,简单的银行存钱取钱程序

题目&#xff1a; 代码实现&#xff1a; BankAccount部分&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Bank {internal class BankAccount{private decimal balance 0;//账…

黑马智数Day5

表单校验 表单基础校验 // 1. 创建表单规则 data() {return {addRules: {name: [{ required: true, message: 企业名称为必填, trigger: blur }],legalPerson: [{ required: true, message: 法人为必填, trigger: blur }],registeredAddress: [{ required: true, message: 注…

《CUDA编程》3.简单CUDA程序的基本框架

本章将学习CUDA程序的基本框架&#xff0c;编写更加有用的CUDA程序 0 C例子&#xff1a;数组相加 C代码如下&#xff1a; #include <math.h> #include <stdio.h> #include <stdlib.h> #include <time.h> // 包含 time.h 头文件以使用 clock()const d…