def simplify_pdf(pdf: str, select: str, outfile: typing.TextIO): """ Given a PDF and a metric by which to select the first or last page in a range of pages with the same name, remove the unnecessary pages """ in_pdf = pdfrw.PdfFileReader(pdf) out_pdf = pdfrw.PdfFileWriter(trailer=in_pdf) for index in calculate_pages(in_pdf, select): out_pdf.addPage(in_pdf.getPage(index)) out_pdf.write(outfile)
def add_metadata_to_pdf(ctx: Context): """ Adds metadata about EDLM version and source files after PDF create Args: ctx: Context """ out_file = str(ctx.out_file.absolute()) trailer = pdfrw.PdfReader(out_file) trailer.Info.Creator = 'EDLM ' + __version__ trailer.Info.Producer = 'EDLM ' + _get_document_hash(ctx) pdfrw.PdfFileWriter(out_file, trailer=trailer).write()
def draw_image(self, page_number, image_file, x, y, width, height, rotation=0): image_path = os.path.join(current.request.folder, "temp", uuid.uuid4().hex + ".jpg") with open(image_path, "wb+") as f: f.write(image_file.read()) if rotation: image = Image.open(image_path) image.rotate(rotation, expand=True).save(image_path) layer_path = os.path.join(current.request.folder, "temp", uuid.uuid4().hex + ".pdf") canv = canvas.Canvas(layer_path, pagesize=(self._LAYER_SIZE_X, self._LAYER_SIZE_Y)) canv.drawImage(image_path, x, y, width=width, height=height) canv.save() layer = pdfrw.PdfReader(layer_path) output_file = pdfrw.PdfFileWriter() input_path = os.path.join(current.request.folder, "temp", uuid.uuid4().hex + ".pdf") with open(input_path, "wb+") as f: f.write(self.pdf_stream) input_file = pdfrw.PdfReader(input_path) for i in range(len(input_file.pages)): if i == page_number - 1: merger = pdfrw.PageMerge(input_file.pages[i]) merger.add(layer.pages[0]).render() output_file.write(self._final_path_with_image, input_file) with open(self._final_path_with_image, "rb+") as f: self.pdf_stream = f.read() os.remove(image_path) os.remove(layer_path) os.remove(input_path) os.remove(self._final_path_with_image) return self
def draw_text( self, text: str, page_number: int, x: Union[float, int], y: Union[float, int], ) -> "_PyPDFForm": """Draw a text on a PDF form.""" self._validate_template(self.stream) self._validate_draw_text_inputs(text, page_number, x, y) input_file = pdfrw.PdfReader(fdata=self.stream) canv_buff = BytesIO() c = canv.Canvas( canv_buff, pagesize=( float(input_file.pages[page_number - 1].MediaBox[2]), float(input_file.pages[page_number - 1].MediaBox[3]), ), ) c.drawString(x, y, text) c.save() canv_buff.seek(0) output_file = pdfrw.PdfFileWriter() for i in range(len(input_file.pages)): if i == page_number - 1: merger = pdfrw.PageMerge(input_file.pages[i]) merger.add( pdfrw.PdfReader(fdata=canv_buff.read()).pages[0]).render() result_stream = BytesIO() output_file.write(result_stream, input_file) result_stream.seek(0) self.stream = result_stream.read() canv_buff.close() result_stream.close() return self
def draw_image( self, image_stream: bytes, page_number: int, x: Union[float, int], y: Union[float, int], width: Union[float, int], height: Union[float, int], rotation: Union[float, int], ) -> "_PyPDFForm": """Draw an image on a PDF form.""" self._validate_template(self.stream) self._validate_draw_image_inputs(page_number, x, y, width, height, rotation) input_file = pdfrw.PdfReader(fdata=self.stream) buff = BytesIO() buff.write(image_stream) buff.seek(0) try: image = Image.open(buff) except Exception: raise InvalidImageError image_buff = BytesIO() image.rotate(rotation, expand=True).save(image_buff, format=image.format) image_buff.seek(0) canv_buff = BytesIO() c = canv.Canvas( canv_buff, pagesize=( float(input_file.pages[page_number - 1].MediaBox[2]), float(input_file.pages[page_number - 1].MediaBox[3]), ), ) c.drawImage(ImageReader(image_buff), x, y, width=width, height=height) c.save() canv_buff.seek(0) output_file = pdfrw.PdfFileWriter() for i in range(len(input_file.pages)): if i == page_number - 1: merger = pdfrw.PageMerge(input_file.pages[i]) merger.add( pdfrw.PdfReader(fdata=canv_buff.read()).pages[0]).render() result_stream = BytesIO() output_file.write(result_stream, input_file) result_stream.seek(0) self.stream = result_stream.read() buff.close() image_buff.close() canv_buff.close() result_stream.close() return self
def _fill_pdf_canvas(self): template_pdf = pdfrw.PdfReader(self._template_path) layers = [] for i in range(len(template_pdf.pages)): layer_path = os.path.join(current.request.folder, "temp", uuid.uuid4().hex + ".pdf") layers.append(layer_path) canv = canvas.Canvas(layer_path, pagesize=(self._LAYER_SIZE_X, self._LAYER_SIZE_Y)) canv.setFont(self._CANVAS_FONT, self._global_font_size) annotations = template_pdf.pages[i][self._ANNOT_KEY] if annotations: for j in reversed(range(len(annotations))): annotation = annotations[j] if (annotation[self._SUBTYPE_KEY] == self._WIDGET_SUBTYPE_KEY and annotation[self._ANNOT_FIELD_KEY]): key = annotation[self._ANNOT_FIELD_KEY][1:-1] if key in self._data_dict.keys(): if self._data_dict[key] in [ pdfrw.PdfName.Yes, pdfrw.PdfName.Off, ]: annotation.update( pdfrw.PdfDict(AS=self._data_dict[key], Ff=pdfrw.PdfObject(1))) else: coordinates = annotation[self._ANNOT_RECT_KEY] annotations.pop(j) if len(self._data_dict[key] ) < self._max_txt_length: canv.drawString( float(coordinates[0]), (float(coordinates[1]) + float(coordinates[3])) / 2 - 2, self._data_dict[key], ) else: txt_obj = canv.beginText(0, 0) start = 0 end = self._max_txt_length while end < len(self._data_dict[key]): txt_obj.textLine( (self._data_dict[key][start:end])) start += self._max_txt_length end += self._max_txt_length txt_obj.textLine( self._data_dict[key][start:]) canv.saveState() canv.translate( float(coordinates[0]), (float(coordinates[1]) + float(coordinates[3])) / 2 - 2, ) canv.drawText(txt_obj) canv.restoreState() else: annotations.pop(j) canv.save() pdfrw.PdfWriter().write(self._output_path, template_pdf) output_file = pdfrw.PdfFileWriter() input_file = pdfrw.PdfReader(self._output_path) for i in range(len(template_pdf.pages)): layer_pdf = pdfrw.PdfReader(layers[i]) os.remove(layers[i]) input_page = input_file.pages[i] merger = pdfrw.PageMerge(input_page) if len(layer_pdf.pages) > 0: merger.add(layer_pdf.pages[0]).render() output_file.write(self._final_path, input_file)