def write_pdf(exhibits: list[Exhibit], output_path: str): """Save the given list of exhibits to a PDF document.""" writer = PdfWriter() for exhibit in exhibits: reader = PdfReader(fdata=exhibit.canvas.getpdfdata()) writer.addpages(reader.pages) writer.write(output_path)
def trace_net(net, net_name, steps=100): import imageio, io from pdfrw import PdfReader, PdfWriter test_env = gym.make('Sokograph-v0', split='valid') s = test_env.reset() with torch.no_grad(): net.eval() imgs = [] tqdm_trace = tqdm(desc='Creating trace', unit=' steps', total=steps) for step in range(steps): fig, _, _ = get_plotly(net, test_env, s, title=f"{net_name} | step {test_env.step_idx} ({test_env.num_env_steps})") imgs.append(fig.to_image(format='pdf')) # make a regular step a, n, v, pi = net([s]) actions = to_action(a, n, [s], size=config.soko_size) s, r, d, i = test_env.step(actions[0]) tqdm_trace.update() writer = PdfWriter() for img in imgs: pdf_img = PdfReader(io.BytesIO(img)).pages writer.addpages(pdf_img) writer.write('trace.pdf') net.train()
def generate_single_pdf(exam, start, end, output_file): """Generates a single pdf file with all the copies joined together. It can be used as a shorthand of `generate_pdfs` where the parameters to be passed are returned by `_exam_generate_data`. If `start == end`, then a single copy is generated. Parameters ---------- exam : Exam The exam to generate the pdfs for start : int The start copy number end : int The final copy number, included output_file : file like object where to write the pdf, needs to implement a write function. """ exam_dir, _, barcode_widget, exam_path, _ = _exam_generate_data(exam) writer = PdfWriter() for copy_num, pdf in generate_pdfs(exam_pdf_file=exam_path, copy_nums=list(range(start, end + 1)), exam_token=exam.token, datamatrix_x=barcode_widget.x, datamatrix_y=barcode_widget.y): writer.addpages(PdfReader(pdf).pages) writer.write(output_file)
def build_zip(record_summary: RecordSummary, user_information: Dict[str, str]) -> Tuple[str, str]: temp_dir = mkdtemp() zip_dir = mkdtemp() zip_name = "expungement_packet.zip" zip_path = path.join(zip_dir, zip_name) zipfile = ZipFile(zip_path, "w") for case in record_summary.record.cases: case_without_deleted_charges = replace( case, charges=tuple(c for c in case.charges if c.edit_status != EditStatus.DELETE)) pdf_with_warnings = FormFilling._build_pdf_for_case( case_without_deleted_charges, user_information) if pdf_with_warnings: pdf, warnings = pdf_with_warnings file_name = f"{case_without_deleted_charges.summary.name}_{case_without_deleted_charges.summary.case_number}.pdf" file_path = path.join(temp_dir, file_name) writer = PdfWriter() writer.addpages(pdf.pages) FormFilling._add_warnings(writer, warnings) trailer = writer.trailer trailer.Root.AcroForm = pdf.Root.AcroForm writer.write(file_path, trailer=trailer) zipfile.write(file_path, file_name) zipfile.close() return zip_path, zip_name
def merge_pdfs(self, pdfs_files, output): """ 合并pdf函数 :param pdfs_files: 输入待合并的文件名数组 :param output: 输出文件名 :return: """ total = len(pdfs_files) progress_signal = 1 self.progressBarValue.emit(progress_signal / total * 100) writer = PdfWriter() for input_filename in pdfs_files: try: writer.addpages(PdfReader(input_filename).pages) progress_signal += 1 # 更新进度条信号 self.progressBarValue.emit(progress_signal / total * 100) # 发信号 except Exception as e: self.work_status.emit("导入文件" + input_filename + "失败") try: writer.write(output) self.work_status.emit("合并pdf文件成功! 文件位置:" + output) except Exception as e: self.work_status.emit("合并失败!" + "原因可能是: 文件名:" + output + "被占用")
def saveAs(self, fname): opdf=PdfWriter() #print type(opdf.trailer), type(opdf.trailer.Info), type(opdf.trailer.Info.Author) opdf.addpages(self.pdf.pages) opdf.trailer.Info=self.pdf.Info opdf.trailer.Root.Outlines=self.pdf.Root.Outlines opdf.write(fname)
def save_with_even_pages(exam_id, exam_pdf_file): """Save a finalized exam pdf with evem number of pages. The exam is saved in the path returned by `get_exam_dir(exam_id)` with the name `exam.pdf`. If the pdf has an odd number of pages, an extra blank page is added at the end, this is specially usefull for printing and contatenating multiple copies at once. Parameters ---------- exam_id : int The exam identifier exam_pdf_file : str or File like object The exam pdf to be saved inthe data directory """ os.makedirs(exam_dir(exam_id), exist_ok=True) pdf_path = exam_pdf_path(exam_id) exam_pdf = PdfReader(exam_pdf_file) pagecount = len(exam_pdf.pages) if (pagecount % 2 == 0): exam_pdf_file.seek(0) exam_pdf_file.save(pdf_path) return new = PdfWriter() new.addpages(exam_pdf.pages) blank = PageMerge() box = exam_pdf.pages[0].MediaBox blank.mbox = box blank = blank.render() new.addpage(blank) new.write(pdf_path)
def book_list(request): if request.method == 'POST': books = Book.objects.all() book_num = len(books) writer = PdfWriter() for book in books: if book: writer.addpages(PdfReader(book.pdf).pages) with open(os.path.join('media', 'mergedfile.pdf'), 'wb') as pdfOutputFile: writer.write(pdfOutputFile) response = FileResponse( open(os.path.join('media', 'mergedfile.pdf'), 'rb')) response['content_type'] = "application/octet-stream" response[ 'Content-Disposition'] = 'attachment; filename="mergedfile.pdf"' books.delete() return response else: books = Book.objects.all() return render(request, 'book_list.html', {'books': books})
def saveAs(self, fname): opdf = PdfWriter() #print type(opdf.trailer), type(opdf.trailer.Info), type(opdf.trailer.Info.Author) opdf.addpages(self.pdf.pages) opdf.trailer.Info = self.pdf.Info opdf.trailer.Root.Outlines = self.pdf.Root.Outlines opdf.write(fname)
def massive_merge(self): # Comprueba si la carpeta de destino y la carpeta de origen son válidas # Carga los nombres en partes y los nombres de archivo completos if path.isdir(self.source_folder.text()) and path.isdir( self.dest_folder.text()): splitted_names, pdf_files = self.load_files( self.source_folder.text()) # Toma el orden de los archivos desde la lista del pdf_order_widget order_list = [ str(self.pdf_order_widget.item(i).text()) for i in range(self.pdf_order_widget.count()) ] print(f'order list: {order_list}') if order_list: # toma la lista con los números de póliza únicamente polizas = list(set([x[0] for x in splitted_names])) print(f'polizas : {polizas}') progress = QProgressDialog("Unificando archivos...", "Abortar", 0, len(polizas), self) progress.setWindowModality(Qt.WindowModal) try: for poliza in polizas: progress.setValue(polizas.index(poliza)) pdf_merger = PdfWriter() for part in order_list: pattern = str(poliza + "[_\s]" + part + ".*") r = re.compile(pattern) file_name = list(filter(r.match, pdf_files)) print(f'file_name: {file_name}') if file_name: fullfile_name = path.join( self.source_folder.text(), file_name[0]) pdf_merger.addpages( PdfReader(fullfile_name).pages) file_dest = path.join(self.dest_folder.text(), '.'.join([poliza, 'pdf'])) print(f'file dest: {file_dest}') pdf_merger.write(file_dest) # pdf_merger.close() if progress.wasCanceled(): break progress.setValue(len(polizas)) self.dialog_message( 'La Unificación masiva ha concluído con éxito!', QMessageBox.Information) except Exception as e: self.dialog_message(str(e), QMessageBox.Warning) else: self.dialog_message( 'La lista con el orden de las partes está vacía, por favor cargue los archivos!', QMessageBox.Warning) else: self.dialog_message( 'La carpeta de origen o destino es inválida, ' 'Por favor ingrese carpetas válidas!', QMessageBox.Warning)
def concatenate(paths, output): writer = PdfWriter() for path_x in paths: reader = PdfReader(path_x) writer.addpages(reader.pages) writer.write(output)
def save_pdf(infile, outpages): trailer = PdfReader(infile) outfn = create_filename(infile) writer = PdfWriter() writer.addpages(outpages) writer.trailer.Info = trailer.Info writer.trailer.Info.Producer = "https://github.com/sgelb/impositioner" writer.write(outfn)
def concat(ifiles, ofile): """Concatenate the given input files (pdf) to the output file. All files with full path. """ writer = PdfWriter() for fi in ifiles: writer.addpages(PdfReader(fi).pages) writer.write(ofile)
def merger(inputs, output): o = open(settings.MEDIA_URL + output, "wb+") writer = PdfWriter() for inpfn in inputs: writer.addpages(PdfReader(settings.MEDIA_URL + inpfn).pages) writer.write(o.name) o.close() return o
def merge_pdf(pdf_list): pdf_io = tempfile.mktemp(suffix=".pdf") writer = PdfWriter() for pdfFileObj in pdf_list: writer.addpages(PdfReader(fdata=pdfFileObj).pages) writer.write(pdf_io) return pdf_io
def merge(self): writer = PdfWriter() files = [x for x in os.listdir('.') if x.endswith('.pdf')] for fname in sorted(files): writer.addpages(PdfReader(os.path.join('.', fname)).pages) writer.write("output.pdf")
def save_pdf(infile, outpages) -> None: trailer = PdfReader(infile) outfn = create_filename(infile) writer = PdfWriter() writer.addpages(outpages) writer.trailer.Info = trailer.Info writer.trailer.Info.Producer = "https://github.com/sgelb/impositioner" writer.write(outfn)
def combine_match_sheets(match_sheets): output_fn = os.path.join(match_sheet_dir, "combined_match_sheets.pdf") writer = PdfWriter() for match_sheet in match_sheets: writer.addpages(PdfReader(match_sheet).pages) writer.write(output_fn) return output_fn
def combine_match_sheets(match_sheets): output_fn = os.path.join(match_sheet_dir,'combined_match_sheets.pdf') writer = PdfWriter() for match_sheet in match_sheets: writer.addpages(PdfReader(match_sheet).pages) writer.write(output_fn) return output_fn
def merge_pdf(person_dir, uuid_name, pdf_name, cfg): to = cfg['TMP_UNMERGED_DEST'] + uuid_name + '/' writer = PdfWriter() for root, dirs, files in os.walk(to): files.sort() for file in files: writer.addpages(PdfReader(os.path.join(to, file)).pages) writer.write(person_dir + "/" + pdf_name) remove_dir(to)
def _add_warnings(writer: PdfWriter, warnings: List[str]): if warnings: text = "# Warnings from RecordSponge \n" text += "Do not submit this page to the District Attorney's office. \n \n" for warning in warnings: text += f"\* {warning} \n" blank_pdf_bytes = MarkdownToPDF.to_pdf("Addendum", text) blank_pdf = PdfReader(fdata=blank_pdf_bytes) writer.addpages(blank_pdf.pages)
def __init__(self, dest, *args): if len(args) < 2: raise Exception('Need at least 2 files to append to each other.') writer = PdfWriter() for fname in args: writer.addpages(get_document_pages(fname)) writer.write(dest)
def join_files(input_files, output_file): """input_files is a list of file objects or path names output_file can be file object or path name""" # standard PdfWriter does not copy AcroForm objects # modified from https://stackoverflow.com/a/57687160 output = PdfWriter() output_acroform = None for pdf in input_files: input = PdfReader(pdf, verbose=False) output.addpages(input.pages) if (PdfName("AcroForm") in input[PdfName("Root")].keys() ): # Not all PDFs have an AcroForm node source_acroform = input[PdfName("Root")][PdfName("AcroForm")] if PdfName("Fields") in source_acroform: output_formfields = source_acroform[PdfName("Fields")] else: output_formfields = [] if output_acroform == None: # copy the first AcroForm node output_acroform = source_acroform else: for key in source_acroform.keys(): # Add new AcroForms keys if output_acroform already existing if key not in output_acroform: output_acroform[key] = source_acroform[key] # Add missing font entries in /DR node of source file if (PdfName("DR") in source_acroform.keys()) and ( PdfName("Font") in source_acroform[PdfName("DR")].keys()): if PdfName("Font") not in output_acroform[PdfName( "DR")].keys(): # if output_acroform is missing entirely the /Font node under an existing /DR, simply add it output_acroform[PdfName("DR")][PdfName( "Font")] = source_acroform[PdfName("DR")][PdfName( "Font")] else: # else add new fonts only for font_key in source_acroform[PdfName("DR")][PdfName( "Font")].keys(): if (font_key not in output_acroform[PdfName("DR")][ PdfName("Font")]): output_acroform[PdfName("DR")][PdfName( "Font")][font_key] = source_acroform[ PdfName("DR")][PdfName( "Font")][font_key] if PdfName("Fields") not in output_acroform: output_acroform[PdfName("Fields")] = output_formfields else: # Add new fields output_acroform[PdfName("Fields")] += output_formfields output.trailer[PdfName("Root")][PdfName("AcroForm")] = output_acroform output.write(output_file)
def merge(): writer = PdfWriter() files = [x for x in os.listdir('uploads') if x.endswith('.pdf')] for fname in sorted(files): writer.addpages(PdfReader(os.path.join('uploads', fname)).pages) writer.write("output.pdf") #On supprime les fichiers stockés en local files = os.listdir('./uploads/') for f in files: os.remove('./uploads/' + f) return render_template("fusion.html")
def add_payload(name, output, path): print('[*] Reading PDF file: %s' % name) reader = PdfReader(name) print('[*] Injecting the payload in the PDF file...') reader.pages[0].AA = PdfDict( O=PdfDict(F=r'%s' % path, D=[0, PdfName('Fit')], S=PdfName('GoToE'))) writer = PdfWriter() writer.addpages(reader.pages) print('[*] Saving modified PDF as: %s' % output) writer.write(output) print('[*] Done!')
def pdfMerge(files_folder): files = [] pdf_writer = PdfWriter() for root, directories, files in os.walk(files_folder): for file in files: if ('.pdf' in file and 'sample' in file): pdf_writer.addpages( PdfReader("%s/%s" % (files_folder, file)).pages ) pdf_writer.write("%s/mergedPDF.pdf" % files_folder)
def Add_Title_Page(input_file, title_file, output_file, page): # define the reader and writer objects reader_input = PdfReader(input_file) writer_output = PdfWriter() watermark_input = PdfReader(title_file) watermark = watermark_input.pages[page] writer_output.addpage(watermark) writer_output.addpages(reader_input.pages) writer_output.write(output_file)
def merge_pdfs(fname_list, output_name="output.pdf"): from PyPDF2 import PdfFileReader, PdfFileMerger import PyPDF2 import img2pdf from pdfrw import PdfReader, PdfWriter writer = PdfWriter() for inpfn in fname_list: decrypt_pdf(inpfn, output_name) writer.addpages(PdfReader(output_name).pages) writer.write(output_name)
def concatenate(paths, output): writer = PdfWriter() for path in paths: reader = PdfReader(path) writer.addpages(reader.pages) writer.trailer.Info = IndirectPdfDict(Title='Combined PDF Title', Author='Michael Driscoll', Subject='PDF Combinations', Creator='The Concatenator') writer.write(output)
def processFile(file): inpfn = file outfn = 'out\\' + os.path.basename(inpfn) reader = PdfReader(inpfn) writer = PdfWriter(outfn) sorter = [None] * len(reader.pages) for idx, page in enumerate(reader.pages): sorter[len(sorter) - idx - 1] = page writer.addpages(sorter) writer.write()
def pdfrw(pdf_files, output): writer = PdfWriter() for inpfn in pdf_files: writer.addpages(PdfReader(inpfn).pages) writer.trailer.Info = IndirectPdfDict( Title='HPA Design', Author='HPA Design', Subject='HPA Design', Creator='HPA Design', ) writer.write(output) return output
def retrieve_images_into_pdf(): if pfile == "": # or pfile.endswith(".pdf"): messagebox.showerror("File Error-> Not PDF","Please select PDF file") else: from pdfrw import PdfReader, PdfWriter from pdfrw.findobjs import page_per_xobj ofile = 'extract.' + os.path.basename(pfile) pages = list(page_per_xobj(PdfReader(pfile).pages, margin=0.5*72)) if not pages: raise IndexError("No XObjects found") writer = PdfWriter(ofile) writer.addpages(pages) writer.write() messagebox.showinfo("Images retrieved","All images saved in '{0}'".format(ofile))
def extract_first_page(fname): # create a temporary PDF file path_tmpfile = os.path.join(tempfile.gettempdir(), os.path.basename(fname)) # extract all elements from the PDF and put them on separate pages pdf_reader = PdfReader(fname).pages pages = list(page_per_xobj(pdf_reader)) # write to temp file writer = PdfWriter(path_tmpfile) writer.addpages(pages) writer.write() return path_tmpfile
def merge(*varargs,merge_file): if(merge_file.endswith('.pdf')): merge_file = merge_file+".pdf" for x in varargs: if(isinstance(x,str) == False): raise Exception("Errore: Tutti i parametri devono essere stringhe.") writer = PdfWriter() files = [] for x in varargs : if x.endswith('.pdf'): files.add(x) else: raise Exception("Errore tutti i parametri devono terminare con .pdf") for fname in sorted(files): writer.addpages(PdfReader(os.path.join('pdf_file', fname)).pages) writer.write("output.pdf")
def consolidateAllSheets(self, subDir=None): """ not sure if this is neccessary or maybe I can send multiple sheets to the browser """ writer = PdfWriter() if subDir != None: directory = self.printdirectory+subDir else: directory = self.printdirectory files = [x for x in os.listdir(directory) if x.endswith('.pdf')] for fname in sorted(files): writer.addpages(PdfReader(os.path.join(directory, fname)).pages) writer.write(directory+"output.pdf") for x in os.listdir(directory): if x == 'output.pdf': continue else: os.remove(directory+x)
def merge(*varargs, filenameOut='merge_file'): if (len(varargs) <=1): raise Exception('Errore: utilizzare almeno due file.') if(not (isinstance(filenameOut,str)) ): raise Exception('Errore: filenameOut deve essere una stringa.') if(filenameOut.endswith('.pdf') == False): filenameOut = filenameOut + ".pdf" writer = PdfWriter() for fname in varargs: if(isinstance(fname,str) == False): raise ValueError("Errore: Tutti i parametri devono essere stringhe.") if not fname.endswith('.pdf'): raise Exception("Errore: tutti i parametri devono terminare con .pdf") reader = PdfReader(fname) writer.addpages(reader.pages) writer.write(filenameOut)
from pdfrw import PdfReader, PdfWriter, IndirectPdfDict import codecs def PDF_string_encoding(unicode_string): return codecs.BOM_UTF16_BE + unicode_string.encode("utf-16be") parser = OptionParser() parser.add_option("-f","--file",dest="inputname",help="input file") parser.add_option("-o","--output",dest="outputname",help="output file") parser.add_option("-t","--title",dest="title",help="title name") parser.add_option("-a","--author",dest="author",help="author name") parser.add_option("-c","--creator",dest="creator",help="creator name") parser.add_option("-s","--subject",dest="subject",help="subject") (opts,args) = parser.parse_args() inputs = opts.inputname assert inputs outfn = opts.outputname assert outfn writer = PdfWriter() #for inpfn in inputs: writer.addpages(PdfReader(inputs, decompress=False).pages) writer.trailer.Info = IndirectPdfDict( Title = PDF_string_encoding(unicode(opts.title,encoding='utf-8')), Author = PDF_string_encoding(unicode(opts.author,encoding='utf-8')), Subject = PDF_string_encoding(unicode(opts.subject,encoding='utf-8')), Creator = PDF_string_encoding(unicode(opts.creator,encoding='utf-8')), ) writer.write(outfn)
#!/usr/bin/env python ''' usage: extract.py <some.pdf> Locates Form XObjects and Image XObjects within the PDF, and creates a new PDF containing these -- one per page. Resulting file will be named extract.<some.pdf> ''' import sys import os from pdfrw import PdfReader, PdfWriter from pdfrw.findobjs import page_per_xobj inpfn, = sys.argv[1:] outfn = 'extract.' + os.path.basename(inpfn) pages = list(page_per_xobj(PdfReader(inpfn).pages, margin=0.5*72)) if not pages: raise IndexError("No XObjects found") writer = PdfWriter() writer.addpages(pages) writer.write(outfn)
import sys import argparse import itertools from pdfrw import PdfWriter, PdfReader parser = argparse.ArgumentParser(description='Interlaces two pdf to make one complete pdf.') parser.add_argument('front_pdf_loc', type=str, help="PDF of fronts of pages") parser.add_argument('back_pdf_loc', type=str, help="PDF of backs of pages") parser.add_argument('output_loc', type=str, nargs='?', default="output.pdf", help="Output location for interlaced PDF") args = parser.parse_args() output = PdfWriter() front_pdf = PdfReader(args.front_pdf_loc) back_pdf = PdfReader(args.back_pdf_loc) if len(front_pdf.pages) != len(back_pdf.pages): print("PDFs must have the same number of pages") sys.exit(1) output.addpages(itertools.chain.from_iterable(zip(front_pdf.pages, back_pdf.pages[::-1]))) output.write(args.output_loc)
argParser.add_argument("-a", "--author", help="Author of PDF") argParser.add_argument("-t", "--title", help="Title of PDF") args = argParser.parse_args() if args.filename is None: print "No filename given" sys.exit(-1) fileInfo = PdfFileReader(file(args.filename)).getDocumentInfo() if args.author is None: author = str(fileInfo.author) if fileInfo.author is not None else None else: author = args.author if args.title is None: title = str(fileInfo.title) if fileInfo.title is not None else None else: title = args.title try: metaWriter = PdfWriter() metaWriter.addpages(PdfReader(args.filename).pages) metaWriter.trailer.Info = IndirectPdfDict(Title=title, Author=author) metaWriter.write(args.filename) except errors.PdfParseError as e: print "Error parsing PDF:", e.msg sys.exit(-1) sys.exit(0)
from pdfrw import PdfReader, PdfWriter pages = PdfReader(r'book_008.pdf', decompress=False).pages other_pages = PdfReader(r'WebSocket.pdf', decompress=False).pages print type(pages) #print pages[0]['/Parent'] writer = PdfWriter() writer.addpages(pages) writer.addpages(other_pages) #print PdfReader('book_008.pdf').values writer.write(r'out.pdf')
except ImportError: print("Instale em seu sistema a biblioteca pdfrw!\n\n") print("sudo apt install python3-pdfrw\n") quit() # Limpa o \n do final da linha na lista def remove_quebra_de_linha(linha): return linha.replace('\n', '') # Vai ser o responsável em escrever o PDFao writer = PdfWriter() # Lista contendo arquivos pdf, linha a linha, com o caminho completo do sistema de arquivos # Deve estar algo como: # /home/meu_usuario/arquivos_pdf/arquivo1.pdf # /home/meu_usuario/arquivos_pdf/arquivo2.pdf pdf_list = open("my_pdfs.txt") # caminho completo do arquivo de saída. Dessa forma abaixo, gera na pasta do script pdefao = 'super.pdf' # Lê linha a linha da lista de pdfs e adiciona ao arquivao for arquivo in pdf_list: arquivo = remove_quebra_de_linha(arquivo) writer.addpages(PdfReader(arquivo).pages) writer.write(pdefao)
''' usage: unspread.py my.pdf Creates unspread.my.pdf Chops each page in half, e.g. if a source were created in booklet form, you could extract individual pages. ''' import sys import os from pdfrw import PdfReader, PdfWriter, PageMerge def splitpage(src): ''' Split a page into two (left and right) ''' # Yield a result for each half of the page for x_pos in (0, 0.5): yield PageMerge().add(src, viewrect=(x_pos, 0, 0.5, 1)).render() inpfn, = sys.argv[1:] outfn = 'unspread.' + os.path.basename(inpfn) writer = PdfWriter() for page in PdfReader(inpfn).pages: writer.addpages(splitpage(page)) writer.write(outfn)
def open_resume(self, resume): r = PdfWriter() r.addpages(resume) pdf_name = self.info["Name"] + ".pdf" r.write(pdf_name) os.system("start " + pdf_name)
1) Concatenating multiple input PDFs. 2) adding metadata to the PDF. If you do not need to add metadata, look at subset.py, which has a simpler interface to PdfWriter. ''' import sys import os import find_pdfrw from pdfrw import PdfReader, PdfWriter, IndirectPdfDict inputs = sys.argv[1:] assert inputs outfn = 'output.pdf' writer = PdfWriter() for inpfn in inputs: writer.addpages(PdfReader(inpfn.pages) writer.trailer.Info = IndirectPdfDict( Title = 'your title goes here', Author = 'your name goes here', Subject = 'what is it all about?', Creator = 'some script goes here', ) writer.write(outfn)