async def addIdentity(pdf, annotationItem:AnnotationDetail): try: sizePapper= pdf.get_size(annotationItem.page - 1) xStart= annotationItem.x yStart= sizePapper[1] - (annotationItem.y) # Keep image ration at 1:1 imageHeight = annotationItem.height * 0.8 xEnd= xStart + imageHeight yEnd= yStart - (annotationItem.height * 0.8) imageLocation = "Member/" + annotationItem.identification.encryptedUserId + "/" + annotationItem.identification.imageFileName pdf.add_annotation( 'image', Location(x1= xStart, y1= yEnd, x2= xEnd, y2= yStart, page= annotationItem.page - 1), Appearance(stroke_width= 0, image= imageLocation), ) xEnd= xStart + annotationItem.width yStart= yStart - (annotationItem.height * 0.8) yEnd= yStart - (annotationItem.height * 0.2) textIdentification= annotationItem.identification.name + "\n" + annotationItem.identification.code pdf.add_annotation( 'text', Location(x1= xStart, y1= yEnd, x2= xEnd, y2= yStart, page= annotationItem.page - 1), Appearance(fill= [0.1, 0.1, 0.1], stroke_width= 2, font_size= 8, content= textIdentification), ) except Exception as e: #TODO print logging print(str(e))
def _add_image_annotations(self, a, appearance, y1=120, y2=160): # Draw a row of image annotations for each type of image, with a label # on top of the image type x = 10 text_appearance = Appearance( font_size=5, text_baseline=constants.TEXT_BASELINE_BOTTOM, fill=[0, 0, 0] ) a.add_annotation( 'text', Location(x1=x, y1=y2, x2=(x + 20), y2=(y2 + 10), page=0), text_appearance.copy(content='PNG'), ) for png_file in PNG_FILES[:-1]: a.add_annotation( 'image', Location(x1=x, y1=y1, x2=(x + 40), y2=y2, page=0), appearance.copy(image=png_file), ) x += 50 # The last PNG file has transparency, so let's draw a rectangle behind # so you can see that it's transparent. a.add_annotation( 'square', Location(x1=x, y1=y1, x2=(x + 40), y2=y2, page=0), self.gaudy.copy(stroke_width=0), ) a.add_annotation( 'image', Location(x1=x, y1=y1, x2=(x + 40), y2=y2, page=0), appearance.copy(image=PNG_FILES[-1]), ) x += 50 a.add_annotation( 'text', Location(x1=x, y1=y2, x2=(x + 20), y2=(y2 + 10), page=0), text_appearance.copy(content='JPEG'), ) for jpeg_file in JPEG_FILES: a.add_annotation( 'image', Location(x1=x, y1=y1, x2=(x + 40), y2=y2, page=0), appearance.copy(image=jpeg_file), ) x += 50 a.add_annotation( 'text', Location(x1=x, y1=y2, x2=(x + 20), y2=(y2 + 10), page=0), text_appearance.copy(content='GIF'), ) for gif_file in GIF_FILES: a.add_annotation( 'image', Location(x1=x, y1=y1, x2=(x + 40), y2=y2, page=0), appearance.copy(image=gif_file), ) x += 50
def annotate(self, annotations, infile, outfile): """ Annotates a file. Args: annotations: list of annotations (title, rgb color, page #, x1, y1, x2, y2) infile: full path to input file outfile: full path to output file """ annotator = PdfAnnotator(infile) # List of text ranges already defined ranges = [] for title, rgb, page, x1, y1, x2, y2 in annotations: # Highlight text annotator.add_annotation( "square", Location(x1=x1, y1=y1, x2=x2, y2=y2, page=page), Appearance(fill=rgb + (0.3, ), stroke_color=rgb + (0.3, ), stroke_width=0)) if title: # Determine if title text should be in left or right margin if x1 < 250: x1, x2 = max(5, x1 - 35), x1 else: x1, x2 = x2, x2 + 35 # Calculate center of highlight annotation and offset center = y1 + ((y2 - y1) / 2) offset = min(max(5, len(title)), 20) # Set position of text annotation. Handle column layout conflicts. y1, y2 = self.position(ranges, page, x1 >= 250, center, offset) # Add title annotation next to highlight annotator.add_annotation( "text", Location(x1=x1, y1=y1, x2=x2, y2=y2, page=page), Appearance(fill=rgb + (1, ), font_size=7, stroke_width=1, content=title)) # Register range ranges.append((page, 0 if x1 < 250 else 1, y1, y2)) annotator.write(outfile)
def _add_rounded_rectangles(self, a): """Add a few rounded rectangles with different border radii.""" y1, y2 = 360, 410 xs = [10, 60, 110] rxs = [5, 10, 15] rys = [5, 5, 15] for x1, rx, ry in zip(xs, rxs, rys): x2 = x1 + 40 location = Location(x1=x1, y1=y1, x2=x2, y2=y2, page=0) content_stream = ContentStream([ Save(), StrokeColor(1, 0, 0), FillColor(0, 1, 0), ]) add_rounded_rectangle( stream=content_stream, x=x1, y=y1, width=(x2 - x1), height=(y2 - y1), rx=rx, ry=ry, ) content_stream.extend([ StrokeAndFill(), Restore(), ]) appearance = Appearance(appearance_stream=content_stream, ) a.add_annotation('square', location, appearance)
def draw_bounding_poly_pdf( self, pdf: PdfReader, vertices: List[Dict], color: AnyStr, ): """Annotate a PDF document by drawing a bounding polygon of a given color Args: pdf: PDF document opened with pdfrw.PdfReader vertices: List of 4 vertices describing the polygon Each vertex should a dictionary with normalized coordinates e.g. {"x": 0.1, "y": 0.3} color: Name of the color e.g. "red", "teal", "skyblue" Full list on https://matplotlib.org/3.3.2/gallery/color/named_colors.html """ if len(vertices) == 4: pdf_annotator = PdfAnnotator(pdf) pdf_annotator.set_page_dimensions( dimensions=(1, 1), page_number=0) # normalize page dimensions pdf_annotator.add_annotation( annotation_type="polygon", location=Location( points=[(vertices[i].get("x", 0.0), 1.0 - vertices[i].get("y", 0.0)) for i in range(4)], page=0, ), appearance=Appearance(stroke_color=colors.to_rgba(color)), ) else: raise ValueError( f"Bounding polygon does not contain 4 vertices: {vertices}") return pdf
def _add_explicit_graphics_state_annotation(self, a): graphics_states = { 'BevelSquare': GraphicsState( line_join=constants.LINE_JOIN_BEVEL, line_cap=constants.LINE_CAP_SQUARE, stroke_transparency=0.75, ), 'MiterButt': GraphicsState( line_join=constants.LINE_JOIN_MITER, line_cap=constants.LINE_CAP_BUTT, stroke_transparency=0.5, ), 'RoundRound': GraphicsState( line_join=constants.LINE_JOIN_ROUND, line_cap=constants.LINE_CAP_ROUND, stroke_transparency=0.25, ), } # Defines the bounding box of the chevrons x1, y1, x2, y2 = 60, 310, 100, 350 lines_location = Location(x1=x1, y1=y1, x2=x2, y2=y2, page=0) # Defines the start/end of the chevrons x1, midpoint, x2 = 65, 80, 95 y1 = 315 content_stream = ContentStream([ Save(), StrokeWidth(5), CSGraphicsState('BevelSquare'), Move(x1, y1), Line(midpoint, y1 + 10), Line(x2, y1), Stroke(), CSGraphicsState('MiterButt'), Move(x1, y1 + 10), Line(midpoint, y1 + 20), Line(x2, y1 + 10), Stroke(), CSGraphicsState('RoundRound'), Move(x1, y1 + 20), Line(midpoint, y1 + 30), Line(x2, y1 + 20), Stroke(), Restore(), ]) appearance = Appearance( appearance_stream=content_stream, graphics_states=graphics_states, ) a.add_annotation( 'square', location=lines_location, appearance=appearance, )
async def addText(pdf, annotationItem: AnnotationDetail): try: sizePapper = pdf.get_size(annotationItem.page - 1) xStart = annotationItem.x yStart = sizePapper[1] - (annotationItem.y) if annotationItem.width == 0: xEnd = sizePapper[0] else: xEnd = xStart + annotationItem.width yEnd = yStart - annotationItem.height textUsed = annotationItem.text pdf.add_annotation( 'text', Location(x1=xStart, y1=yEnd, x2=xEnd, y2=yStart, page=annotationItem.page - 1), Appearance(fill=[1, 0, 0], stroke_width=1, font_size=9, content=textUsed), ) except Exception as e: #TODO print logging print(str(e))
def _add_explicit_image_annotation(self, a): """Add an image annotation using ContentStream commands instead of the Image type's commands. This is testing that the external XObjects API works, and that images can be embedded inside other, more complex annotations. """ x1, y1, x2, y2 = 10, 310, 50, 350 location = Location(x1=x1, y1=y1, x2=x2, y2=y2, page=0) content_stream = ContentStream([ StrokeColor(1, 0, 0), Rect(x1, y1, x2 - x1, y2 - y1), Save(), # The image is inside an outer rectangle CTM(Image.get_ctm(x1 + 10, y1 + 10, x2 - 10, y2 - 10)), XObject('MyXObject'), Restore(), Stroke(), ]) appearance = Appearance( appearance_stream=content_stream, xobjects={ 'MyXObject': Image.make_image_xobject(PNG_FILES[0]), }, ) a.add_annotation( 'square', location=location, appearance=appearance, )
def annotate_text(self, text: 'parse_pdf.Text', color=BLUE): loc = Location(x1=text.x_min, y1=self.page_height - text.y_max, x2=text.x_max, y2=self.page_height - text.y_min, page=text.page) appearance = Appearance(stroke_color=color, stroke_width=1) self.annotations.append(('square', loc, appearance))
def _add_text_annotations(self, a, y1=220, y2=300): xs = [10 + (i * 50) for i in range(len(self.texts))] for x, appearance in zip(xs, self.texts): a.add_annotation( 'text', Location(x1=x, y1=y1, x2=(x + 40), y2=y2, page=0), appearance, )
def redactDocument(dirname, filename, boxes): a = PdfAnnotator(dirname+"/"+filename) for i in boxes: a.add_annotation('square', Location(x1=i[0]*72, y1=(790-i[1]*72), x2=i[2]*72, y2=(790-i[3]*72), page=0), Appearance(stroke_color=(0, 0, 0), stroke_width=13, fill=(0,0,0)),) resultFilename = 'Redacted'+filename a.write(resultFilename) print("[INFO]: Process Completed.") return resultFilename
def pdf_add_Annot_old(path, file, stamp): from pdf_annotate import PdfAnnotator, Location, Appearance a = PdfAnnotator(os.path.join(path, file)) a.add_annotation( 'square', Location(x1=50, y1=50, x2=100, y2=100, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=5), ) a.write(os.path.join( path, 'new_w_stamp.pdf')) # or use overwrite=True if you feel lucky
def redactDocument(dirname, filename, boxes): print("Dirname: " + dirname[0:len(dirname) - 14]) print("Filename: " + filename) dirname = dirname[0:len(dirname) - 14] a = PdfAnnotator(dirname+filename) for i in boxes: a.add_annotation('square', Location(x1=i[0]*72, y1=(790-i[1]*72), x2=i[2]*72, y2=(790-i[3]*72), page=0), Appearance(stroke_color=(0, 0, 0), stroke_width=13, fill=(0,0,0)),) a.write(dirname + filename) print("[INFO]: Process Completed.") return dirname + filename
def annotate_group(self, texts: List['parse_pdf.Text'], color=BLUE): x1 = min(t.x_min for t in texts) x2 = max(t.x_max for t in texts) y1 = min(t.y_min for t in texts) y2 = min(t.y_max for t in texts) loc = Location(x1=x1, y1=self.page_height - y2, x2=x2, y2=self.page_height - y1, page=texts[0].page) appearance = Appearance(stroke_color=color, stroke_width=1) self.annotations.append(('square', loc, appearance))
def _add_shape_annotations(self, a, appearance, y1=20, y2=60): a.add_annotation( 'square', Location(x1=10, y1=y1, x2=50, y2=y2, page=0), appearance, ) a.add_annotation( 'circle', Location(x1=60, y1=y1, x2=100, y2=y2, page=0), appearance, ) a.add_annotation( 'polygon', Location(points=[[110, y1], [150, y1], [130, y2]], page=0), appearance, ) a.add_annotation( 'polyline', Location(points=[[160, y1], [200, y1], [180, y2]], page=0), appearance, ) a.add_annotation( 'line', Location(points=[[210, y1], [250, y2]], page=0), appearance, ) a.add_annotation( 'ink', Location(points=[[260, y1], [300, y2]], page=0), appearance, ) round = appearance.copy(line_cap=constants.LINE_CAP_ROUND) a.add_annotation( 'line', location=Location(points=[[310, y1], [350, y2]], page=0), appearance=round, ) dashed = appearance.copy(dash_array=[[3], 0]) a.add_annotation( 'line', location=Location(points=[[360, y1], [400, y2]], page=0), appearance=dashed, )
async def addPolyLine(pdf, annotationItem:AnnotationDetail): try: sizePapper= pdf.get_size(annotationItem.page - 1) # Penyesuaian titik coordinat (0,0) dan titik start line # karena di python leftbottom di javascript lefttop y = sizePapper[1] - annotationItem.y for idx in range(len(annotationItem.points)): point = annotationItem.points[idx] annotationItem.points[idx]= [point[0] + annotationItem.x, y - point[1]] pdf.add_annotation( 'polyline', Location(points= annotationItem.points, page= annotationItem.page - 1), Appearance(stroke_color= (1, 0, 0), stroke_width= 4), ) except Exception as e: #TODO print logging print(str(e))
def test_add_annotation_page_dimensions(self): # Ensure that changing a page's dimensions results in annotations being # placed in the proper locations. a = PdfAnnotator(files.SIMPLE) # Act like the PDF was rastered at 144 DPI (2x default user space) a.set_page_dimensions((1224, 1584), 0) a.add_annotation( 'square', Location(x1=10, y1=20, x2=20, y2=30, page=0), Appearance(), ) with write_to_temp(a) as t: annotations = load_annotations_from_pdf(t) square = annotations.pop() assert len(annotations) == 0 assert square.Subtype == '/Square' # The outer bounding box of the square is padded outward by the stroke # width, and then scaled down by two. self.assertEqual(square.Rect, ['4.5', '9.5', '10.5', '15.5'])
def _add_explicit_text_annotation(self, a): x1, y1, x2, y2 = 110, 310, 200, 350 font_size = 4 content_stream = ContentStream([ Save(), BeginText(), FillColor(0, 0, 0), Font('MyFontyFont', font_size), ]) content_stream.extend( get_text_commands( x1, y1, x2, y2, text=(r'Twas brilling and the slithy toves \n' r'Did gyre and gimbel in the wabe \n' r'All mimsy were the borogroves \n' r'And the mome raths outgrabe \n'), font_size=font_size, wrap_text=True, align=constants.TEXT_ALIGN_LEFT, baseline=constants.TEXT_BASELINE_TOP, line_spacing=1.2, )) content_stream.extend([ EndText(), Restore(), ]) appearance = Appearance( appearance_stream=content_stream, fonts={'MyFontyFont': FreeText.make_font_object()}, ) a.add_annotation( 'square', location=Location(x1=x1, y1=y1, x2=x2, y2=y2, page=0), appearance=appearance, )
a.set_page_dimensions((pdf_dim[i][0], pdf_dim[i][1]), 0) pos_x1 = pdf_dim[i][2] pos_x2 = pdf_dim[i][3] pos_y1 = pdf_dim[i][4] pos_y2 = pdf_dim[i][5] for wall in geschoss.walls: x = (wall.x) / (dim_geschoss[i][0]) * (pos_x2 - pos_x1) + pos_x1 y = (wall.y) / (dim_geschoss[i][1]) * (pos_y1 - pos_y2) + pos_y2 x2 = (wall.x + wall.dx) / (dim_geschoss[i][0]) * (pos_x2 - pos_x1) + pos_x1 y2 = (wall.y + wall.dy) / (dim_geschoss[i][1]) * (pos_y1 - pos_y2) + pos_y2 a.add_annotation( "square", Location(x1=x, y1=y, x2=x2, y2=y2, page=0), Appearance(stroke_color=(0, 0, 0), stroke_width=2), ) for room in geschoss.rooms: for obj in room.objects: x = (obj.x) / (dim_geschoss[i][0]) * (pos_x2 - pos_x1) + pos_x1 y = (obj.y) / (dim_geschoss[i][1]) * (pos_y1 - pos_y2) + pos_y2 r = 100 color = (0, 1, 1) if obj.print_name in ["Steckdose"]: pic_file = "steckdose_{}.png".format(obj.anzahl) elif obj.print_name in ["Stromanschluss"]: pic_file = "stromanschluss.png" if obj.knx == KnxType.Rolladen: pic_file = "rolladen.png"
def process_drawing_stamps(self): try: os.mkdir(f'{self.file_path_drawing_to_stamp}/Stamped') except Exception as e: print(e) self.ui.listWidget_drawing_stamper.clear() self.ui.listWidget_drawing_stamper.addItem("Unable to create directory - error code below:\n") self.ui.listWidget_drawing_stamper.addItem(str(e)) today = date.today() today_date = today.strftime("%d/%m/%y") drawing_status = "" if self.ui.radioButton_status_a.isChecked() == True: drawing_status = "A" elif self.ui.radioButton_status_b.isChecked() == True: drawing_status = "B" elif self.ui.radioButton_status_c.isChecked() == True: drawing_status = "C" else: drawing_status = "Unknown" self.ui.listWidget_drawing_stamper.clear() self.ui.listWidget_drawing_stamper.addItem("Adding annotations:\n") for drawing in self.list_of_drawingstostamp: try: full_drawing_path = self.file_path_drawing_to_stamp + '/' + drawing self.ui.listWidget_drawing_stamper.addItem(drawing) QtCore.QCoreApplication.processEvents() full_path_drawing_stamp = self.file_path_drawing_to_stamp + "/Blank_Stamp.png" a = PdfAnnotator(full_drawing_path) a.add_annotation( 'image', Location(x1=50, y1=50, x2=400, y2=400, page=0), Appearance(image=full_path_drawing_stamp) ) except Exception as e: print("Unable to add image") try: a.add_annotation( 'text', Location(x1=120, y1=320, x2=300, y2=332, page=0), Appearance(stroke_color=(1, 1, 1), stroke_width=5, content=self.ui.lineEdit_drawing_stamper_jobnumber.text(), fill=(0.705, 0.094, 0.125, 1)) ) #https://doc.instantreality.org/tools/color_calculator/ a.add_annotation( 'text', Location(x1=130, y1=305, x2=300, y2=317, page=0), Appearance(stroke_color=(1, 1, 1), stroke_width=5, content=self.ui.lineEdit_drawing_stamper_date.text(), fill=(0.705, 0.094, 0.125, 1)) ) a.add_annotation( 'text', Location(x1=75, y1=276, x2=300, y2=288, page=0), Appearance(stroke_color=(1, 1, 1), stroke_width=5, content=self.ui.lineEdit_drawing_stamper_reviewerinitials.text(), fill=(0.705, 0.094, 0.125, 1)) ) a.add_annotation( 'text', Location(x1=200, y1=276, x2=320, y2=288, page=0), Appearance(stroke_color=(1, 1, 1), stroke_width=5, content=f"Status {drawing_status}", fill=(0.705, 0.094, 0.125, 1)) ) a.add_annotation( 'text', Location(x1=330, y1=276, x2=400, y2=288, page=0), Appearance(stroke_color=(1, 1, 1), stroke_width=5, content=today_date, fill=(0.705, 0.094, 0.125, 1)) ) # Put an X in the box noting the status if drawing_status == "A": a.add_annotation( 'text', Location(x1=117, y1=203, x2=300, y2=215, page=0), Appearance(stroke_color=(1, 1, 1), stroke_width=5, content="X", fill=(0.705, 0.094, 0.125, 1)) ) if drawing_status == "B": a.add_annotation( 'text', Location(x1=117, y1=189, x2=300, y2=201, page=0), Appearance(stroke_color=(1, 1, 1), stroke_width=5, content="X", fill=(0.705, 0.094, 0.125, 1)) ) if drawing_status == "C": a.add_annotation( 'text', Location(x1=117, y1=174, x2=300, y2=186, page=0), Appearance(stroke_color=(1, 1, 1), stroke_width=5, content="X", fill=(0.705, 0.094, 0.125, 1)) ) except Exception as e: print(e) self.ui.listWidget_drawing_stamper.addItem("Unable to add annotation - error code below:\n") self.ui.listWidget_drawing_stamper.addItem(str(e)) self.ui.listWidget_drawing_stamper.addItem("Check - is this file a PDF?") try: #Write the resultant file a.write(f'{self.file_path_drawing_to_stamp}/Stamped/{drawing}') except Exception as e: print(e) self.ui.listWidget_drawing_stamper.addItem("Unable to save file - error code below:\n") self.ui.listWidget_drawing_stamper.addItem(str(e)) self.ui.listWidget_drawing_stamper.addItem("Check - do these files already exist?") return #Display success message self.ui.listWidget_drawing_stamper.clear() self.ui.listWidget_drawing_stamper.addItem("Stamps added successfully!") return
def annotate_cols(self, cols: List[float], page: int): for col in cols: loc = Location(points=[[col, 0], [col, self.page_height]], page=page) appearance = Appearance(stroke_color=RED, stroke_width=2) self.annotations.append(('line', loc, appearance))
def draw_rectangles_for_solution(self, f_in, f_out, solution, points): """Drawing green filled rectangles near the correct answers for every problem, in order to indicate the correct solution. It calculates and writes the total score achieved too. Parameters: f_in (str): Path to the input PDF file. f_out (str): Path to the output PDF file. solution (dict): The solution (correct answers) corresponding to the input PDF file (f_in). points (float): Total points achieved. """ pr = PdfFileReader(f_in) dest = pr.getNamedDestinations() fields = pr.getFields() # """IT IS NOT WORKING IF THIS COMES FIRST:""" # a = PdfAnnotator(f_in) # for p in range(pr.getNumPages()): # for dk, dv in dest.items(): # if pr.getDestinationPageNumber(dv) == p and dk.startswith('ht_'): # inds = [int(ind) for ind in dk[3:].split(':')] # # if inds[2] in solution[inds[1]][1]: # if inds[4] in solution[inds[1]][1]: # # using some hard-coded values: # a.add_annotation('square', # Location(x1=float(dv['/Left']), y1=float(dv['/Top']), x2=float(dv['/Left'])+5, y2=float(dv['/Top'])+5, page=p), # Appearance(stroke_color=(0, 1, 0), stroke_width=5),) # a.write(f_out) pw = PdfFileWriter() # pr = PdfFileReader(f_out, strict=False) pr = PdfFileReader(f_in, strict=False) pw.appendPagesFromReader(pr) pw._root_object.update( {NameObject("/AcroForm"): pr.trailer["/Root"]["/AcroForm"]}) pw._root_object["/AcroForm"].update( {NameObject("/NeedAppearances"): BooleanObject(True)}) for p in range(pr.getNumPages()): self._update_page_form_checkbox_values(pw.getPage(p), { fk: fv['/V'] for fk, fv in fields.items() if '/V' in fv.keys() }) # sometimes '/V' disappears from the keys self._update_page_form_checkbox_values(pw.getPage(0), {'points': str(points)}) f = codecs.open(f_out, 'wb') pw.write(f) f.close() a = PdfAnnotator(f_out) for p in range(pr.getNumPages()): for dk, dv in dest.items(): if pr.getDestinationPageNumber(dv) == p and dk.startswith( 'ht_'): inds = [int(ind) for ind in dk[3:].split(':')] # if inds[2] in solution[inds[1]][1]: if inds[4] in solution[inds[1]][1]: # using some hard-coded values: a.add_annotation( 'square', Location(x1=float(dv['/Left']), y1=float(dv['/Top']), x2=float(dv['/Left']) + 5, y2=float(dv['/Top']) + 5, page=p), Appearance(stroke_color=(0, 1, 0), stroke_width=5), ) a.write(f_out)
from pdfscrape import Scraped_PDF import PyPDF2 import os from pdf_annotate import PdfAnnotator, Appearance, Location annotator = PdfAnnotator(os.getcwd()+'/trade_tickets/Company_Q2_p1.pdf') annotator.add_annotation('square',Location(x1=300, y1=265, x2=500, y2=330, page=0),Appearance(stroke_color=(1, 0, 0), stroke_width=3),) annotator.write('annotated.pdf') class Annotate(object): def __init__(self, pdf_obj):
#!/usr/bin/env vpython3 from pdf_annotate import PdfAnnotator, Location, Appearance annotationtext = "some text" a = PdfAnnotator("pdf.pdf") a.add_annotation( "text", Location(x1=50, y1=50, x2=200, y2=100, page=0), Appearance( fill=(0, 0, 0), stroke_width=1, wrap_text=True, font_size=12, content=annotationtext, ), ) a.write("pdf-a.pdf")
def generate_timesheet(form): # Setting default strings sunday_in = '' monday_in = '' tuesday_in = '' wednesday_in = '' thursday_in = '' friday_in = '' saturday_in = '' sunday_out = '' monday_out = '' tuesday_out = '' wednesday_out = '' thursday_out = '' friday_out = '' saturday_out = '' sunday_hours = '' monday_hours = '' tuesday_hours = '' wednesday_hours = '' thursday_hours = '' friday_hours = '' saturday_hours = '' fund = '' def calc_hours_worked(time_in, time_out): hours = datetime.datetime.combine( datetime.date.today(), time_out.data) - datetime.datetime.combine( datetime.date.today(), time_in.data) return round(hours.seconds / 3600, 2) def next_saturday(d): if d.weekday() == 5: return d else: days_ahead = 5 - d.weekday() if days_ahead < 0: days_ahead += 7 return d + datetime.timedelta(days_ahead) def previous_sunday(d): if d.weekday() == 6: return d else: days_behind = -d.weekday() - 1 return d + datetime.timedelta(days_behind) name = form['name'].data mcgill_id = form['mcgill_id'].data hourly_rate = round(float(form['hourly_rate'].data), 2) if form['fund_number'].data is not None: fund = form['fund_number'].data week = datetime.date(int(form['week_of_year'].data), int(form['week_of_month'].data), int(form['week_of_day'].data)) # find the closest past sunday week_start = previous_sunday(week) # find the closest future saturday week_end = next_saturday(week) total_hours = 0 if form['sunday_in'].data is not None and form[ 'sunday_out'].data is not None: sunday_in = form['sunday_in'].data.strftime('%H:%M') sunday_out = form['sunday_out'].data.strftime('%H:%M') sunday_hours = calc_hours_worked(form['sunday_in'], form['sunday_out']) total_hours += sunday_hours if form['monday_in'].data is not None and form[ 'monday_out'].data is not None: monday_in = form['monday_in'].data.strftime('%H:%M') monday_out = form['monday_out'].data.strftime('%H:%M') monday_hours = calc_hours_worked(form['monday_in'], form['monday_out']) total_hours += monday_hours if form['tuesday_in'].data is not None and form[ 'tuesday_out'].data is not None: tuesday_in = form['tuesday_in'].data.strftime('%H:%M') tuesday_out = form['tuesday_out'].data.strftime('%H:%M') tuesday_hours = calc_hours_worked(form['tuesday_in'], form['tuesday_out']) total_hours += tuesday_hours if form['wednesday_in'].data is not None and form[ 'wednesday_out'].data is not None: wednesday_in = form['wednesday_in'].data.strftime('%H:%M') wednesday_out = form['wednesday_out'].data.strftime('%H:%M') wednesday_hours = calc_hours_worked(form['wednesday_in'], form['wednesday_out']) total_hours += wednesday_hours if form['thursday_in'].data is not None and form[ 'thursday_out'].data is not None: thursday_in = form['thursday_in'].data.strftime('%H:%M') thursday_out = form['thursday_out'].data.strftime('%H:%M') thursday_hours = calc_hours_worked(form['thursday_in'], form['thursday_out']) total_hours += thursday_hours if form['friday_in'].data is not None and form[ 'friday_out'].data is not None: friday_in = form['friday_in'].data.strftime('%H:%M') friday_out = form['friday_out'].data.strftime('%H:%M') friday_hours = calc_hours_worked(form['friday_in'], form['friday_out']) total_hours += friday_hours if form['saturday_in'].data is not None and form[ 'saturday_out'].data is not None: saturday_in = form['saturday_in'].data.strftime('%H:%M') saturday_out = form['saturday_out'].data.strftime('%H:%M') saturday_hours = calc_hours_worked(form['saturday_in'], form['saturday_out']) total_hours += saturday_hours total_money = round(total_hours * hourly_rate, 2) if form['timesheet_template'].data == '1': base_timesheet = 'academic_casual_timesheet_-_2017_0.pdf' annotations = constants.annotations_academic_casual_timesheet personal_data = constants.personal_data_academic_casual_timesheet else: base_timesheet = 'admin_support_staff_casual_employee_timesheet_-_2017.pdf' annotations = constants.annotations_admin_support_staff_casual_employee_timesheet personal_data = constants.personal_data_admin_support_staff_casual_employee_timesheet pdf_out_dir = 'pdf/' out_file = form['name'].data + ' ' + week_start.strftime( '%d %b %Y') + '.pdf' # out_file = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)]) + '.pdf' out_path = pdf_out_dir + out_file department = 'Building 21' signature_date = datetime.date.today() timesheet = PdfAnnotator(base_timesheet) for annotation in annotations: x1 = annotation[1] y1 = annotation[2] x2 = x1 + annotation[3] y2 = y1 + annotation[4] timesheet.add_annotation( 'text', Location(x1=x1, y1=y1, x2=x2, y2=y2, page=0), Appearance(content=str(eval(annotation[0])), fill=(0, 0, 0), text_baseline='bottom'), ) for annotation in personal_data: x1 = annotation[1] y1 = annotation[2] x2 = x1 + annotation[3] y2 = y1 + annotation[4] timesheet.add_annotation( 'text', Location(x1=x1, y1=y1, x2=x2, y2=y2, page=0), Appearance(content=str(eval(annotation[0])), fill=(0, 0, 0), text_baseline='middle', text_align='center'), ) timesheet.write('static/' + out_path) return out_path
def scrape_pdf(self): pdfFileObject = open(os.getcwd() + "/" + self.path, 'rb') pdf_info = list( filter( lambda x: any(c.isalnum() for c in x), PyPDF2.PdfFileReader(pdfFileObject).getPage( 0).extractText().split('\n'))) for i, x in enumerate(pdf_info): pdf_info[i] = x.strip() annotator = PdfAnnotator(os.getcwd() + self.path) annotated = False self.company_name = pdf_info[1] if pdf_info.index('Trans Type') == pdf_info.index('Quantity') - 2: self.transaction_type = pdf_info[pdf_info.index('Trans Type') + 1] else: self.transaction_type = None annotator.add_annotation( 'square', Location(x1=80, y1=435, x2=140, y2=490, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True if pdf_info.index('Quantity') == pdf_info.index('PPS') - 2: self.quantity = int(pdf_info[pdf_info.index('Quantity') + 1].replace(',', '')) else: self.quantity = None annotator.add_annotation( 'square', Location(x1=160, y1=435, x2=220, y2=490, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True if pdf_info.index('PPS') == pdf_info.index('Security') - 2: self.price_per_share = int( pdf_info[pdf_info.index('PPS') + 1][1:len(pdf_info[pdf_info.index('PPS') + 1]) - 3]) else: self.price_per_share = None annotator.add_annotation( 'square', Location(x1=225, y1=435, x2=285, y2=490, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True if len(pdf_info[3]) > 14: self.date_of_order = pdf_info[3][15:] else: print("date of order missing") self.date_of_order = None annotator.add_annotation( 'square', Location(x1=150, y1=570, x2=280, y2=590, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True if len(pdf_info[4]) > 10: self.custodian = pdf_info[4][11:] else: self.custodian = None annotator.add_annotation( 'square', Location(x1=130, y1=540, x2=280, y2=565, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True if pdf_info.index('Security') == pdf_info.index('Type of Order') - 2: self.security = pdf_info[pdf_info.index('Security') + 1] else: self.security = None annotator.add_annotation( 'square', Location(x1=295, y1=435, x2=360, y2=490, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True if pdf_info.index( 'Type of Order') == pdf_info.index('Instructions') - 2: self.type = pdf_info[pdf_info.index('Type of Order') + 1] else: self.type = None annotator.add_annotation( 'square', Location(x1=360, y1=435, x2=460, y2=490, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True if pdf_info.index('Broker/Dealer') == pdf_info.index( 'Broker/Dealer Representative') - 2: self.broker_dealer = pdf_info[pdf_info.index('Broker/Dealer') + 1] else: self.broker_dealer = None annotator.add_annotation( 'square', Location(x1=70, y1=330, x2=285, y2=400, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True if pdf_info.index('Broker/Dealer Representative' ) == pdf_info.index('Comments:') - 2: self.broker_dealer_representative = pdf_info[ pdf_info.index('Broker/Dealer Representative') + 1] else: self.broker_dealer_representative = None annotator.add_annotation( 'square', Location(x1=300, y1=330, x2=500, y2=400, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True if pdf_info.index('Phone:') == pdf_info.index('Signature:') - 3: self.phone = pdf_info[pdf_info.index('Phone:') + 1] + "-" + pdf_info[pdf_info.index('Phone:') + 2] else: self.phone = None annotator.add_annotation( 'square', Location(x1=300, y1=265, x2=500, y2=330, page=0), Appearance(stroke_color=(1, 0, 0), stroke_width=3), ) annotated = True try: self.amount = self.quantity * self.price_per_share except: self.amount = None if annotated: # os.mkdir(os.getcwd() + "/ANNOTATED/trade_tickets") annotator.write(os.getcwd() + "/ANNOTATED" + self.path) # else maybe move it to the completed folder self.valid_pdf = self.amount != None and self.transaction_type != None and self.quantity != None pdfFileObject.close()
def create_annotation(node: PdfAnnotator, is_name: bool, count: int, value): coordinate_dict_name = { '1': { 'x1': 95, 'y1': 720, 'x2': 160, 'y2': 740 }, '2': { 'x1': 335, 'y1': 720, 'x2': 405, 'y2': 740 }, '3': { 'x1': 95, 'y1': 690, 'x2': 160, 'y2': 710 }, '4': { 'x1': 335, 'y1': 690, 'x2': 405, 'y2': 710 } } coordinate_dict_id = { '1': { 'x1': 215, 'y1': 720, 'x2': 295, 'y2': 740 }, '2': { 'x1': 465, 'y1': 720, 'x2': 550, 'y2': 740 }, '3': { 'x1': 215, 'y1': 690, 'x2': 295, 'y2': 710 }, '4': { 'x1': 465, 'y1': 690, 'x2': 550, 'y2': 710 } } if is_name: return node.add_annotation( 'text', Location(x1=coordinate_dict_name[str(count)]['x1'], y1=coordinate_dict_name[str(count)]['y1'], x2=coordinate_dict_name[str(count)]['x2'], y2=coordinate_dict_name[str(count)]['y2'], page=0), Appearance(stroke_color=(0, 0, 0), stroke_width=5, content=value, fill=(0, 0, 0, 1))) else: return node.add_annotation( 'text', Location(x1=coordinate_dict_id[str(count)]['x1'], y1=coordinate_dict_id[str(count)]['y1'], x2=coordinate_dict_id[str(count)]['x2'], y2=coordinate_dict_id[str(count)]['y2'], page=0), Appearance(stroke_color=(0, 0, 0), stroke_width=5, content=value, fill=(0, 0, 0, 1)))
def annotatePDF(pathToPDF): try: randomNumber1 = str(randint(0, 9)) randomNumber2 = str(randint(1000, 9999)) a = PdfAnnotator(pathToPDF) #Name and adress a.add_annotation( 'text', Location(x1=350, y1=590, x2=560, y2=650, page=0), Appearance(content=name + "\n" + adress + "\n" + city.upper(), font_size=11, fill=(0, 0, 0), line_spacing=1.8), ) #Edition date a.add_annotation( 'text', Location(x1=393, y1=550, x2=570, y2=573, page=0), Appearance(content=beautifulDate, font_size=9, fill=(0, 0, 0), line_spacing=1.65), ) #Request number a.add_annotation( 'text', Location(x1=1.37 * 72, y1=8.23 * 72, x2=3.58 * 72, y2=8.40 * 72, page=0), Appearance(content=date + '-' + randomNumber1 + '-' + randomNumber2, font_size=9, fill=(0, 0, 0), line_spacing=1.65), ) #name and date of birth a.add_annotation( 'text', Location(x1=0.73 * 72, y1=8 * 72, x2=2.1 * 72, y2=8.3 * 72, page=0), Appearance(content=lastName.upper() + ' le : ' + birthDate, font_size=9, fill=(0, 0, 0), line_spacing=1.5), ) #PrelevementDateTime a.add_annotation( 'text', Location(x1=1.32 * 72, y1=7.43 * 72, x2=3 * 72, y2=7.7 * 72, page=0), Appearance(content=date + ' . ' + hour, font_size=9, fill=(0, 0, 0), line_spacing=1.1), ) #ValidationDate1 a.add_annotation( 'text', Location(x1=5.34 * 72, y1=1.75 * 72, x2=5.85 * 72, y2=1.93 * 72, page=0), Appearance(content=date, font_size=9, fill=(0, 0, 0), line_spacing=1.1), ) #ValidationDate2 a.add_annotation( 'text', Location(x1=3.6 * 72, y1=0.45 * 72, x2=4.1 * 72, y2=0.60 * 72, page=0), Appearance(content=date, font_size=9, fill=(0, 0, 0), line_spacing=1.1), ) #Create a new file a.write(pathToPDF.replace('inputs', 'outputs')) return 'Done' except Exception as e: return e