吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 220|回复: 4
收起左侧

[其他求助] 帮忙生成一个可执行的程序

[复制链接]
lengyuqf 发表于 2025-12-25 17:02
25吾爱币
本人不太会使用软件编程,麻烦帮忙生成一下,看看效果。功能是实现PDF根据上传的名单批量加水印,然后生成到对应的文件夹
[Python] 纯文本查看 复制代码
from PyPDF2 import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from io import BytesIO
import re
import os
import pandas as pd

def clean_filename(filename):
    """移除文件名中的非法字符"""
    return re.sub(r'[\\/*?:"<>|\n]', '_', filename)

def create_watermark(name, page_width=992, page_height=792, font_size=20, alpha=0.15, gap=150):
    packet = BytesIO()
    can = canvas.Canvas(packet, pagesize=(page_width, page_height))
    
    # 设置中文字体
    try:
        from reportlab.pdfbase.ttfonts import TTFont
        from reportlab.pdfbase import pdfmetrics
        pdfmetrics.registerFont(TTFont('SimSun', 'C:/Windows/Fonts/simsun.ttc'))  # Windows 宋体
        can.setFont("SimSun", font_size)
    except:
        can.setFont("Helvetica", font_size)  # 回退
    
    can.setFillColorRGB(0.1, 0.1, 0.1, alpha=alpha)
    
    # 计算水印分布
    x_vals = range(-int(gap * 2), int(page_width + gap * 2), gap)
    y_vals = range(-int(gap * 2), int(page_height + gap * 2), gap)
    
    can.saveState()
    for x in x_vals:
        for y in y_vals:
            can.saveState()
            can.translate(x, y)
            can.rotate(45)
            
            # 处理换行文本
            lines = name.split('\n')
            line_height = font_size * 1.2
            for i, line in enumerate(lines):
                y_offset = - (len(lines) - 1) * line_height / 2 + i * line_height
                can.drawCentredString(0, y_offset, line)
            
            can.restoreState()
    can.restoreState()
    
    can.save()
    packet.seek(0)
    return PdfReader(packet)

def add_watermark(input_pdf_path, output_pdf_path, watermark_name):
    original = PdfReader(input_pdf_path)
    watermark = create_watermark(watermark_name).pages[0]
    writer = PdfWriter()
    
    for page in original.pages:
        page.merge_page(watermark)
        writer.add_page(page)
    
    with open(output_pdf_path, "wb") as f:
        writer.write(f)

def read_recipients_from_excel(excel_path, sheet_name=0, name_column='姓名', org_column='部门', additional_columns=None):
    """
    从Excel文件中读取接收者列表
    :param excel_path: Excel文件路径
    :param sheet_name: 工作表名称或索引
    :param name_column: 姓名所在列名
    :param org_column: 组织/部门所在列名
    :param additional_columns: 需要添加到水印中的其他列名列表
    :return: 接收者列表(包含组织信息)
    """
    df = pd.read_excel(excel_path, sheet_name=sheet_name)
    
    recipients = []
    for index, row in df.iterrows():
        name = str(row[name_column])
        org = str(row[org_column]) if org_column in row and not pd.isna(row[org_column]) else '未分类'
        
        # 如果有其他列需要添加到水印中
        if additional_columns:
            additional_info = []
            for col in additional_columns:
                if col in row and not pd.isna(row[col]):
                    additional_info.append(str(row[col]))
            if additional_info:
                name += '\n' + '\n'.join(additional_info)
        
        recipients.append({
            'name': name,
            'org': org
        })
    
    return recipients

def batch_add_watermarks(input_pdf_path, recipients, output_base_dir="watermarked_pdfs"):
    """
    批量为不同的人添加水印,并按组织分类
    :param input_pdf_path: 原始PDF文件路径
    :param recipients: 接收者列表,每个元素是包含'name'和'org'的字典
    :param output_base_dir: 输出基础目录
    """
    # 确保基础输出目录存在
    os.makedirs(output_base_dir, exist_ok=True)
    
    # 按组织分组处理
    org_groups = {}
    for recipient in recipients:
        org = recipient['org']
        if org not in org_groups:
            org_groups[org] = []
        org_groups[org].append(recipient)
    
    # 为每个组织创建文件夹并生成PDF
    for org, members in org_groups.items():
        # 创建组织文件夹
        org_dir = os.path.join(output_base_dir, clean_filename(org))
        os.makedirs(org_dir, exist_ok=True)
        
        # 为每个成员生成带水印的PDF
        for member in members:
            name = member['name']
            output_pdf = os.path.join(org_dir, f"watermarked_{clean_filename(name)}.pdf")
            add_watermark(input_pdf_path, output_pdf, name)
            print(f"生成: {output_pdf}")
    
    print(f"\n所有带水印的PDF文件已生成在 {output_base_dir} 目录中")
    print(f"共生成 {len(recipients)} 个PDF文件,分布在 {len(org_groups)} 个组织文件夹中")

if __name__ == "__main__":
    # 示例使用 - 从Excel读取
    try:
        # 从Excel文件读取接收者列表
        # 假设Excel文件中有"姓名"列和"部门"列
        recipients = read_recipients_from_excel(
            'recipients.xlsx',
            name_column='姓名',
            org_column='部门',
            additional_columns=['备注']
        )
        
        # 请将此处替换为你的原始PDF文件路径
        input_pdf = "source.pdf"
        
        # 检查文件是否存在
        if not os.path.exists(input_pdf):
            print(f"错误:未找到文件 {input_pdf}")
            print("请将原始PDF文件放在当前目录下,并命名为 source.pdf")
        else:
            batch_add_watermarks(input_pdf, recipients)
            
    except Exception as e:
        print(f"发生错误: {e}")
        print("\n使用说明:")
        print("1. 确保存在recipients.xlsx文件,包含'姓名'列和'部门'列")
        print("2. 确保存在source.pdf文件")
        print("3. 安装依赖:pip install PyPDF2 reportlab pandas openpyxl")

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Stars313 发表于 2025-12-25 17:42
https://aippt-domestic.oss-accel ... 25174111vrsiauy.jpg
直链,试运行了下,发生错误:
[Errno2]Nosuchfileordirectory:'recipients.xlsx
使用说明:
1.确保存在recipients.xlsx文件,包含·姓名'列和'部门'列
2.确保存在source.pdf文件
3.安装依赖:pipinstallPyPDF2reportlabpandasopenpyxl
liunianwen 发表于 2025-12-25 18:31
本帖最后由 liunianwen 于 2025-12-25 18:32 编辑

这个报错应该是因为,recipients.xlsx文件没有和.exe 文件在同一个文件夹内?如果只有这个报错,那打包好的exe文件本身应该没问题
 楼主| lengyuqf 发表于 2025-12-26 12:21
liunianwen 发表于 2025-12-25 18:31
这个报错应该是因为,recipients.xlsx文件没有和.exe 文件在同一个文件夹内?如果只有这个报错,那打包好 ...

可以的话帮忙生成一个 没问题我就采纳啦
liunianwen 发表于 2025-12-26 13:53
lengyuqf 发表于 2025-12-26 12:21
可以的话帮忙生成一个 没问题我就采纳啦

楼主,一楼的那个就是呀,如果你用他那个运行不报错,那就采纳他的就行,如果不行再说
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-1-2 20:45

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表