在缺少表单输入值的 Python 中填写和展平 pdf 表单

问题描述 投票:0回答:1

我在 Windows Server 2019 标准上使用 Python 3.10 来填写 PDF 表单,然后将其展平,然后作为附件通过电子邮件发送。

我按照这里的说明用 Python 生成扁平化的 PDF。所有选项在大多数情况下都有效,我能够在 Firefox、Chrome 以及 Adobe 阅读器和 Adobe 文档云中打开 PDF。我使用 Adobe Acrobat DC Standard 来创建简单的表单。我尝试的最后一个代码来自上面链接中的 Charalamm。下面的屏幕截图是在尝试 Charalamm 代码之后。 (其他选项即使不相同也有相似的体验)

但是,Outlook 客户端(Microsoft® Outlook® for Microsoft 365)、outlook.office.com 中的预览 PDF 处理程序。未在字段中显示数据或值。它显示文本字段。 office 365一盘,PDF预览显示数据,但是字体很大,我编辑PDF尽量小也改不了

有人知道为什么 PDF 预览不起作用吗? 这是 MS 问题吗?

Outlook客户端PDF预览

One Drive PDF 预览有效,但它会忽略字体大小

Outlook Office 365 网络客户端

使用 pdfrw 包转储字段

import pdfrw

pdf_obj = pdfrw.PdfReader(fillable_file) 

for x in pdf_obj.Root.AcroForm.Fields:
      print(x)

{'/DA': '(/Helv 8 Tf 0 0 1 rg)', '/F': '4', '/FT': '/Tx', '/Ff': '1', '/MK': {}, '/P': (17, 0), '/Rect': ['147.989', '735.367', '297.989', '757.367'], '/Subtype': '/Widget', '/T': '(Text1)', '/Type': '/Annot', '/V': 'This is sample text', '/AP': ''}
python pdf fill preview
1个回答
0
投票

以防万一其他人有类似的问题,我将添加我的解决方案来解决这个问题。我发现的解决方案是可靠的 pdf 库(FPDF 教程)称为

from fpdf import FPDF

这需要更多的跑腿工作,但输出的 PDF 文件在我能够测试的大多数设备上看起来完全一样。我也用过PyPDF

from PyPDF2 import PdfMerger

合并生成的PDF文件。

这完全取决于您如何获取数据,在我的示例中,我有一个包含行的报告 - 对于每个部门,最后一列是礼物类型的列,最后一列是总计。最后一行也是所有部门针对特定礼品类型的总和。数据已经计算好了——在生成报告之前。

例如

# Gift Report
# Headers across the top by type of the gift
# Headers in the first column indicating Departments
# Totals in the last row
# Totals in the last column

# Set PDF properties and insert the background image
pdf = FPDF(orientation = 'L', unit = 'mm', format = 'A4')
pdf.add_page()
pdf.image(self.backgrnd_image, x = 60, y = 60, w = 211, h = 100)

# Add custom fonts - You can use google fonts in your app
pdf.add_font('Lora',
                '',
                self.path_to_fonts + "Lora\static\Lora-Regular.ttf",
                uni=True)
pdf.add_font('LoraItalic',
                '',
                self.path_to_fonts + "Lora\static\Lora-Italic.ttf",
                uni=True)


# TITLE CELL
pdf.set_fill_color(214, 213, 210)
pdf.set_text_color(0,0,0)
pdf.set_font("Lora", size=12, style='U')
pdf.set_xy(10,26)
pdf.cell(0, 12.5, txt='Gift Report', ln=1, align="C" , fill = False)

# SUB TITLE
pdf.set_font("Lora", size=10, style='I')
pdf.set_xy(10,36)
pdf.cell(0, 12.5, txt='This is sample SUBTITLE.', ln=1, align="C" , fill = False)

# REPORT YEAR
pdf.set_font("LoraItalic", size=10, style='B')
pdf.set_xy(135,43)
pdf.cell(10, 10, txt=str(fiscal_year), ln=0, align="C" , fill = False)


# SET UP COLUMN HEADERS: Gift 1, Gift 2... Total by Unit
set_y = 53

pdf.set_font("Arial", size=9, style='B')
pdf.set_xy(70,set_y)
pdf.cell(10, 10, txt="Gift Type 1", ln=0, align="C" , fill = False)

pdf.set_font("Arial", size=9, style='B')
pdf.set_xy(97,set_y)
pdf.cell(10, 10, txt="Gift Type 2", ln=0, align="C" , fill = False)

pdf.set_font("Arial", size=9, style='B')
pdf.set_xy(251,set_y)
pdf.cell(10, 10, txt="Total by Dept", ln=0, align="C" , fill = False)

...


# ROWS - Header names (In first column) on the left

set_y = 60
for row in gift_data:

    # Put space between rows based on the index/position of the element to lay it accurately as possible over image background
    if row[7] == 9: #Dept 1
      set_y = set_y + 6.1

    if row[7] == 13: #Dept 2
      set_y = set_y + 6.1

    if row[7] == 14: #Dept 3
      set_y = set_y + 6.5


# ROWS
pdf.set_font("Arial", size=8, style='')
pdf.set_xy(82,set_y)
pdf.cell(10, 10, txt="$" + "{:,.2f}".format(row[1]), ln=0,  align="R" , fill = False)

pdf.set_font("Arial", size=8, style='')
pdf.set_xy(105,set_y)
pdf.cell(10, 10, txt="$" + "{:,.2f}".format(row[2]), ln=0, align="R" , fill = False)

pdf.set_font("Arial", size=8, style='')
pdf.set_xy(105,set_y)
pdf.cell(10, 10, txt="$" + "{:,.2f}".format(row[2]), ln=0, align="R" , fill = False)

    ...
© www.soinside.com 2019 - 2024. All rights reserved.