Заполнение pdf форм python

Batch fill PDF forms from python or bash

I have a PDF form that needs to be filled out a bunch of times (it’s a timesheet to be exact). Now since I don’t want to do this by hand, I was looking for a way to fill them out using a python script or tools that could be used in a bash script. Does anyone have experience with this?

4 Answers 4

For Python you’ll need the fdfgen lib and pdftk

@Hugh Bothwell’s comment is 100% correct so I’ll extend that answer with a working implementation.

If you’re in windows you’ll also need to make sure both python and pdftk are contained in the system path (unless you want to use long folder names).

Here’s the code to auto-batch-fill a collection of PDF forms from a CSV data file:

import csv from fdfgen import forge_fdf import os import sys sys.path.insert(0, os.getcwd()) filename_prefix = "NVC" csv_file = "NVC.csv" pdf_file = "NVC.pdf" tmp_file = "tmp.fdf" output_folder = './output/' def process_csv(file): headers = [] data = [] csv_data = csv.reader(open(file)) for i, row in enumerate(csv_data): if i == 0: headers = row continue; field = [] for i in range(len(headers)): field.append((headers[i], row[i])) data.append(field) return data def form_fill(fields): fdf = forge_fdf("",fields,[],[],[]) fdf_file = open(tmp_file,"w") fdf_file.write(fdf) fdf_file.close() output_file = ' .pdf'.format(output_folder, filename_prefix, fields[1][1]) cmd = 'pdftk "" fill_form "" output "" dont_ask'.format(pdf_file, tmp_file, output_file) os.system(cmd) os.remove(tmp_file) data = process_csv(csv_file) print('Generating Forms:') print('-----------------------') for i in data: if i[0][1] == 'Yes': continue print('  created. '.format(filename_prefix, i[1][1])) form_fill(i) 

Note: It shouldn’t be rocket-surgery to figure out how to customize this. The initial variable declarations contain the custom configuration.

In the CSV, in the first row each column will contain the name of the corresponding field name in the PDF file. Any columns that don’t have corresponding fields in the template will be ignored.

Читайте также:  Php задать значение массива

In the PDF template, just create editable fields where you want your data to fill and make sure the names match up with the CSV data.

For this specific configuration, just put this file in the same folder as your NVC.csv, NVC.pdf, and a folder named ‘output’. Run it and it automagically does the rest.

This works beautifully. Only thing I had to add was path to PDFtk: code os.environ[‘PATH’] += os.pathsep + ‘C:\\Program Files (x86)\\PDFtk\\bin;’

Much faster version, no pdftk nor fdfgen needed, pure Python 3.6+:

# -*- coding: utf-8 -*- from collections import OrderedDict from PyPDF2 import PdfFileWriter, PdfFileReader def _getFields(obj, tree=None, retval=None, fileobj=None): """ Extracts field data if this PDF contains interactive form fields. The *tree* and *retval* parameters are for recursive use. :param fileobj: A file object (usually a text file) to write a report to on all interactive form fields found. :return: A dictionary where each key is a field name, and each value is a :class:`Field` object. By default, the mapping name is used for keys. :rtype: dict, or ``None`` if form data could not be located. """ fieldAttributes = if retval is None: retval = OrderedDict() catalog = obj.trailer["/Root"] # get the AcroForm tree if "/AcroForm" in catalog: tree = catalog["/AcroForm"] else: return None if tree is None: return retval obj._checkKids(tree, retval, fileobj) for attr in fieldAttributes: if attr in tree: # Tree is a field obj._buildField(tree, retval, fileobj, fieldAttributes) break if "/Fields" in tree: fields = tree["/Fields"] for f in fields: field = f.getObject() obj._buildField(field, retval, fileobj, fieldAttributes) return retval def get_form_fields(infile): infile = PdfFileReader(open(infile, 'rb')) fields = _getFields(infile) return OrderedDict((k, v.get('/V', '')) for k, v in fields.items()) def update_form_values(infile, outfile, newvals=None): pdf = PdfFileReader(open(infile, 'rb')) writer = PdfFileWriter() for i in range(pdf.getNumPages()): page = pdf.getPage(i) try: if newvals: writer.updatePageFormFieldValues(page, newvals) else: writer.updatePageFormFieldValues(page, =' for i, (k, v) in enumerate(get_form_fields(infile).items()) >) writer.addPage(page) except Exception as e: print(repr(e)) writer.addPage(page) with open(outfile, 'wb') as out: writer.write(out) if __name__ == '__main__': from pprint import pprint pdf_file_name = '2PagesFormExample.pdf' pprint(get_form_fields(pdf_file_name)) update_form_values(pdf_file_name, 'out-' + pdf_file_name) # enumerate & fill the fields with their own names update_form_values(pdf_file_name, 'out2-' + pdf_file_name, ) # update the form fields 

Источник

Заполняем PDF файлы с использованием Python: библиотека python-pptx

Нам часто приходится заполнять шаблоны, бланки и прочие документы. Если операция повторяется постоянно, то работу нужно автоматизировать. Сегодня расскажем о создании умного шаблона, а также об автоматизации процесса его заполнения.

Это может помочь, к примеру, в автоматизации заполнения шаблонов презентаций: для ежеквартальный отчетов, выступлений, текущих задач и новых идей.

С одной стороны, создание слайдов – это творческий процесс и при автоматизации пропадает индивидуальный подход и творчество. Но это нет так. Рутинную работу мы передаем роботу, а творчество используем в создании умного шаблона. Преимущества: исключаем ошибки при переносе информации из одного формата (Excel, Word) в другой и отказываемся от ручного процесса переноса.

Впервые автозаполнение слайдов в Power Point с помощью Python — мы использовали для подготовки наградных документов по результатам работы сотрудников за год. Так как номинаций было несколько – получился большой список сотрудников.

Поэтому хотим поделиться своим практическим опытом автоматизации этого процесса. Опираясь на него, вы также сможете создать свой умный шаблон для решения текущих задач.

  • Какие инструменты использовали:Microsoft PowerPoint, Jupyter Notebook, MS Excel, Adobe Photoshop (или можно найти готовый шаблон в сети Интернет)
  • Язык программирования: Python

1. Библиотеку для обработки файлов *.pptx устанавливаем через командную строку или Anaconda Prompt – pip install python-pptx

3. Далее на фоновое изображение необходимо наложить текст и другие элементы, которые будут оставаться неизменными. Используем для этого — MS PowerPoint.

4. Информацию по всем сотрудникам, заявленным к награждению, мы вносим в файл Excel (его же будем использовать как источник данных).

5. Используя инструмент интерактивной разработки Jupyter Notebook импортируем библиотеку pptx и модули этой библиотеки. Для чтения excel импортируем библиотеку xlrd.

from pptx import Presentation from pptx.enum.shapes import … …. import os import xlrd workbook=xlrd.open_workbook(‘./Название файла, содержащего список ФИО награждаемых’)

6. С помощью следующего блока программного кода читаем данные из Excel-листа в Python framework.

worksheet=workbook.sheet_by_index(4) total_rows=worksheet.nrows total_cols=worksheet.ncols table=list() record=list() if total_rows > 0: for x in range(7,total_rows): # не берем строки с 1 по 7, в которых текст и названия столбцов for y in range(total_cols): record.append(worksheet.cell(x,y).value) table.append(record) record = [ ] x=x+1 else: print(«Файл пустой»)

7. Указываем место на локальном диске, в котором будет создана папка для наших наградных электронных документовlocalpath=’c:\\папка_1\\папка_2\\’

8. Создаем функцию, c помощью которой обратим pptx-файл в pdf-файл.

def PPTtoPDF(inputFileName, outputFileName, formatType = 32): powerpoint = comtypes.client.CreateObject(«Powerpoint.Application») powerpoint.Visible = 1 if outputFileName[-3:] != ‘pdf’: outputFileName = outputFileName + «.pdf» deck = powerpoint.Presentations.Open(inputFileName) deck.SaveAs(outputFileName, formatType) # formatType = 32 for ppt to pdf deck.Close() powerpoint.Quit()

9. Соблюдаем правила орфографии и склонения с помощью следующего блока кода:

for i in range(total_rows-7): # не берем первые 7 строк (там «шапка») #print(i) record=table[i] if record[0]!=»»: # если столбец «Кто номинирует» НЕ пустой (в таблице больше строк,чем внесено данных) company=’ООО Ромащка ‘ city= record[4] if city==’МСК’: city=’г.Москва’ companycity=company+city

10. Заполняем информацию по занятым местам:

mesto = str(record[2]) if mesto==’1.0′: mesto=’I’ _mesto=mesto #для имени файла mesto1=’ занявшее в номинации’ # оставляем разное кол-во пробелов для печати места др.цветом mesto2=mesto+» место » if mesto==’2.0′: mesto=’II’ _mesto=mesto #для имени файла mesto1=’ занявшее в номинации’ mesto2=mesto+» место » if mesto==’3.0′: mesto=’III’ _mesto=mesto #для имени файла mesto1=’ занявшее в номинации’ mesto2=mesto+» место » if mesto==’1.5′: mesto=’I-II’ _mesto=mesto #для имени файла mesto1=’ занявшее в номинации’ mesto2=mesto+» место » if mesto==’2.5′: mesto=’II-III’ _mesto=mesto #для имени файла mesto1=’ занявшее в номинации’ mesto2=mesto+» место » if mesto==’3.5′: mesto=’III-IV’ _mesto=mesto #для имени файла mesto1=’ занявшее в номинации’ mesto2=mesto+» место » if mesto==»: _mesto=’победитель’ # для имени файла mesto1=’победитель в номинации’ mesto2=» nom = record[1] za = record[3]

11. Теперь формируем текст для печати, устанавливаем отступы, задаем цвет текстовым слоям:

12. Затем формируем итоговые pdf-файлы (устанавливаем шрифт, цвет, размер)

q=len(dtext) # кол-во элементов для печати nameprs=’ДИПЛОМ’ # ВНИМАНИЕ: шаблоны с именами должны лежать в каталоге вместе с программой prs=Presentation(nameprs + «.pptx») slide = prs.slides[0] shapes = slide.shapes for j in range(1,q+1): shape = shapes.add_shape(MSO_SHAPE.RECTANGLE, Cm(1.25), dtop[j], Cm(25.0), Cm(2)) shape.fill.background() shape.line.fill.background() shape.shadow.inherit = False text_frame = shape.text_frame text_frame.vertical_anchor = MSO_ANCHOR.TOP p = text_frame.paragraphs[0] p.alignment = dalign[j] run = p.add_run() font = run.font font.name = ‘Arial’ font.italic = None # cause value to be inherited from theme font.bold=dfbold[j] #font.color.rgb=RGBColor(38,38,38) font.color.rgb=dfcolor[j] run.text = dtext[j] font.size = dfsize[j] fname=localpath + record[4] +’_’+’ДИПЛОМ’+’_’+ nom +’_’+_mesto+» «+str(i+8) # ИМЯ ВЫХОДНОГО ФАЙЛА_»ДИПЛОМ»_номинация_место_№строки в файле prs.save(fname + ‘.pptx’) PPTtoPDF(fname + ‘.pptx’,fname + ‘.pdf’) #os.remove(fname.replace(‘\\’,’/’)+’.pptx’) не удаляем файл .pptx i=i+1 # закончили формирование дипломов

Итоговый продукт выглядит следующим образом.

Источник

Оцените статью