def print_certidao(self, request, diligencias): """ :param diligencias: :return: """ from weasyprint import HTML, CSS from django.conf import settings from app.models import Diligencia from django.utils import datetime_safe modelo_html = '' for i in range(len(diligencias)): if i == 0: #primeira certidão # '<meta charset="utf-8" />' modelo_html += '<html>' \ '<head>' \ '<meta charset="utf-8" />' \ '<base href="http://ofjusapp.pythonanywhere.com/">'\ '</head>' \ '<body>' \ '<div style="float: none;">' \ '<div>' modelo_html += diligencias[i].documento modelo_html += '</div>' else: #certidões intermediarias modelo_html += '<div style="page-break-before:always;">' modelo_html += diligencias[i].documento modelo_html += '</div>' modelo_html += '</div></body></html>' pdf_html = HTML(string=modelo_html) main_doc = pdf_html.render() pdf_file = main_doc.write_pdf() diligencias.update(imprimir=False) #pdf_file = HTML('http://weasyprint.org/').write_pdf('/tmp/weasyprint-website.pdf') return pdf_file # returns the response.
def form_valid(self, form): self.post_data = self.request.POST if 'download' in self.post_data: html = self.render_to_response(self.get_context_data(form=form)) f = open(os.path.join( os.path.dirname(__file__), './static/payslip/css/payslip.css')) html = HTML(string=html.render().content) pdf = html.write_pdf(stylesheets=[CSS(string=f.read())]) f.close() resp = HttpResponse(pdf, content_type='application/pdf') resp['Content-Disposition'] = \ u'attachment; filename="{}_{}.pdf"'.format( self.date_start.year, self.date_start.month) return resp return self.render_to_response(self.get_context_data(form=form))
def serve_pdf(self, request): # Render html content through html template with context template = get_template(settings.PDF_TEMPLATE) context = {"invoice": self} html = template.render(context) # Write PDF to file document_html = HTML(string=html, base_url=request.build_absolute_uri()) document = document_html.render() if len(document.pages) > 1: for page in document.pages[1:]: str(page) pdf = document.write_pdf() else: pdf = document.write_pdf() # response = HttpResponse(html) response = HttpResponse(pdf, content_type="application/pdf") response["Content-Disposition"] = 'filename="Invoice {0} | Invoice {0}.pdf"'.format(self.id) return response
def print_avisos(self, request, mandados): """ :param mandados: :return: """ from weasyprint import HTML, CSS from django.conf import settings from app.models import Atendimento, Oficial from django.utils import datetime_safe oj = Oficial.objects.get(usuario=request.user) atendimentos = Atendimento.objects.filter(oficial=oj, data__gt=datetime_safe.date.today()) av = Modelo_Documento.objects.get(nome='AVISO') modelo_html = '' for i in range(len(mandados)): if i == 0: #primeiro aviso # '<meta charset="utf-8" />' modelo_html += '<html>' \ '<head>' \ '<meta charset="utf-8" />' \ '</head>' \ '<body>' \ '<div style="float: none;">' \ '<div>' c = template.Context({'mandado':mandados[0], 'atendimentos':atendimentos})#.last()}) t = template.Template(av.modelo) modelo_html += t.render(c) modelo_html += '</div>' else: #avisos intermediarios modelo_html += '<div style="page-break-before:always;">' c = template.Context({'mandado':mandados[i], 'atendimentos':atendimentos})#.last()}) t = template.Template(av.modelo) modelo_html += t.render(c) modelo_html += '</div>' modelo_html += '</div></body></html>' #print(modelo_html) pdf_html = HTML(string=modelo_html) main_doc = pdf_html.render() pdf_file = main_doc.write_pdf() #pdf_file = HTML('http://weasyprint.org/').write_pdf('/tmp/weasyprint-website.pdf') return pdf_file # returns the response.
def generate_pdf(body): html = HTML(string=body) main_doc = html.render() pdf = main_doc.write_pdf() return pdf
def grabPRCY(fileAddr): from grab import Grab def clearStr( string ): if type(string) != type(None): return string.replace('\n','').replace('\t','').replace('\r','') g = Grab() g.go('https://id.pr-cy.ru/signup/login/') g.doc.set_input('login_email','*****@*****.**') g.doc.set_input('password','biksileev') g.doc.submit() output = open('Finished.txt', 'w') j = 1 phant = webdriver.PhantomJS() for string in fileinput.input(fileAddr): customerList = string.split(' ') customerList[2] = clearStr(customerList[2]) phant.get('https://a.pr-cy.ru/' + customerList[1]) time.sleep(60) g.go('https://a.pr-cy.ru/' + customerList[1]) newList = g.css_list('.is') print(len(newList)) i = 0 f = open('audit/' + customerList[1] + '.html','w') f.write('''<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <link rel='stylesheet' href="style.css"> </head> <body> <div id="head"> <img src="biksileev.jpg"/> <h1>Технический аудит сайта http://''' + customerList[1] + '''</h1> <p>Для чёткого понимания текущего технического состояния сайта http://''' + customerList[1] + ''' был проведён полный технический аудит, результаты которого представлены ниже в виде таблицы.</p></div>''') f.write('<div>') f.write('<table>') f.write('<thead><tr><td colspan="2">Технический аудит</td></tr></thead>') f.write('<tbody>') f.write('<tr><td>Критерий</td><td>Текущее состояние</td></tr>') for name in newList: if True: #not('Обратные ссылки' in name.cssselect('.info-test')[0].text) or not('Аналитика' in name.cssselect('.info-test')[0].text): if len(name.cssselect('.info-test')) > 0: print(name.cssselect('.info-test')[0].text) if (('Описание страницы' or 'Скриншот сайта на смартфоне') in name.cssselect('.info-test')[0].text): f.write('</table></div><div class="pageBreak"><table>') f.write('<tr ><td class="left">') else: f.write('<tr><td class="left">') f.write(name.cssselect('.info-test')[0].text) f.write('</td>') f.write(' ') if len(name.cssselect('.content-test')) > 0: if (len(clearStr(name.cssselect('.content-test')[0].text)) > 0): if (name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') elif (name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right unsuccess">') else: f.write('<td class="right">') if (len(name.cssselect('.content-test')[0].cssselect('a')) > 0): f.write(clearStr(name.cssselect('.content-test')[0].text) + clearStr(name.cssselect('.content-test')[0].cssselect('a')[0].text)) else: f.write(clearStr(name.cssselect('.content-test')[0].text)) f.write('</td>') elif (len(name.cssselect('.content-test')[0].cssselect('.iphone .iphone-screen img')) > 0): if (name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') elif (name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right unsuccess">') else: f.write('<td class="right">') f.write('<img src="http://' + name.cssselect('.content-test')[0].cssselect('.iphone .iphone-screen img')[0].get('src')[2:] + '">') f.write('</td>') elif(('Facebook' in name.cssselect('.info-test')[0].text) or ('ВКонтакте' in name.cssselect('.info-test')[0].text) or ('Google+' in name.cssselect('.info-test')[0].text) or ('Twitter' in name.cssselect('.info-test')[0].text)): if(name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') f.write('Ссылка на страницу найдена.') f.write('</td>') elif(name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right unsuccess">') f.write('Ссылка на страницу не найдена.') f.write('</td>') elif ((len(name.cssselect('.content-test')[0].cssselect('a')) > 0)): if (name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') elif (name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right unsuccess">') else: f.write('<td class="right">') f.write(clearStr(name.cssselect('.content-test')[0].cssselect('a')[0].text)) f.write('</td>') elif (len(name.cssselect('.content-test')[0].cssselect('p')) > 0): newList2 = name.cssselect('.content-test')[0].cssselect('p') if (name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') elif (name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right unsuccess">') else: f.write('<td class="right">') for paragraph in newList2: f.write(clearStr(paragraph.text)) f.write('<br>') f.write('</td>') elif (len(name.cssselect('.content-test')[0].cssselect('.progress-info .progress-info')) > 0): if (name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') elif (name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right unsuccess">') else: f.write('<td class="right">') f.write(clearStr(name.cssselect('.content-test')[0].cssselect('.progress-info .progress-info')[0].text)) f.write('</td>') elif (len(name.cssselect('.content-test')[0].cssselect('.progress-info')) > 0): if (name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') elif (name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right unsuccess">') else: f.write('<td class="right">') f.write(clearStr(name.cssselect('.content-test')[0].cssselect('.progress-info')[0].text)) f.write('</td>') elif (len(name.cssselect('.content-test')[0].cssselect('span')) > 0) or ('Системы статистики' in name.cssselect('.info-test')[0].text): if (name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') elif (name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right unsuccess">') else: f.write('<td class="right">') newList2 = name.cssselect('.content-test')[0].cssselect('span') for analytics in newList2: f.write(clearStr(analytics.text)) f.write('<br>') f.write('</td>') elif (len(name.cssselect('.info-test')) > 0): if('Местоположение сервера' in name.cssselect('.info-test')[0].text): if (name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') elif (name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right unsuccess">') else: f.write('<td class="right">') f.write(name.cssselect('.content-test img')[0].get('alt').split(' ')[2]) f.write('</td>') elif('Favicon' in name.cssselect('.info-test')[0].text): if(name.cssselect('.check-test')[0].get('test-status') == 'success'): f.write('<td class="right success">') f.write('Отлично, у сайта есть Favicon.') f.write('</td>') elif(name.cssselect('.check-test')[0].get('test-status') == 'fail'): f.write('<td class="right success">') f.write('Отлично, у сайта есть Favicon.') f.write('</td>') i += 1 '''f.write('<td>') newList3 = name.cssselect('.description p') for paragraph in newList3: f.write(paragraph.text)''' f.write('</tbody>') f.write('</table>') f.write('''<p> Резолюция Сайт частично оптимизирован.</p> </body> </html> ''') f.close() file = HTML(filename="audit/" + customerList[1] + ".html") file.render().write_pdf(target="audit/" + customerList[1] + ".pdf") #file.render('file://' + os.getcwd() + '/audit/' + customerList[1] + '.html', 'audit/' + customerList[1] + '.pdf') subject = customerList[0] + ' - подготовили аудит вашего сайта: ' + customerList[1] message = customerList[0] + """, добрый день! Причина нашего обращения к Вам не случайна. Специалистами студии Дмитрия Биксилеева в течение марта месяца проводился выборочный аудит сайтов компаний работающих в сфере услуг для бизнеса. В том числе был проведен краткий аудит Вашего сайта %s Нашими SEO-специалистами выявлены достаточно серьезные ошибки на сайте, мешающие его продвижению в поисковых системах и снижающие удобство пользования вашим сайтом для ваших потенциальных клиентов (см. приложение «Экспресс аудит сайта»). Как правило, данные ошибки не заметны на первый взгляд, но об их наличии убедительно свидетельствует низкий КПД сайта. Наверное, и Вы сами, как ответственный и экономный хозяин, периодически задаетесь вопросом: Почему сайт, в который вложено столько интеллектуальных и финансовых ресурсов не оправдывает свое существование? Почему клиенты заходят на сайт, но не совершают покупок? Почему Ваши конкуренты уводят клиентов? Мы дадим ответы на все интересующие Вас вопросы и с удовольствием поделимся самыми свежими и самыми необходимыми в XXI веке знаниями по интернет-маркетингу. В случае Вашей заинтересованности, сделаем полный базовый, технический и юзабилити аудит сайта, предложим реальные сроки и способы устранения недостатков и выведем Ваш сайт на лидирующие позиции в поисковиках по самым высоко конверсионным запросам. Мы не предлагаем Вам услуги с непредсказуемым или неубедительным результатом. Мы предлагаем взрывной рост Вашему Интернет-бизнесу! Помогая Вам в бизнесе, мы становимся своеобразным хуком в интернет-продажах, Вашим директором по маркетингу, полностью выстраивающим маркетинг и систему продаж. С уважением к Вам и Вашему бизнесу, Бубновский Михаил Директор по развитию компании Студия Дмитрия Биксилеева ---------------------------------------------------------- Тел.: +7(343)298-03-54 Сот. Тел.: +7 (922)1554515 E-mail: [email protected] skype: ottepel_1 www.biksileev.ru""" % customerList[1] #sendMail(customerList[2], subject, message, 'audit/' + customerList[1] + '.pdf') customerList.append('Отправлено') output.write(' '.join(customerList)) output.write('\n') text1.delete('1.0', str(len(' '.join(customerList) + '\n') + 1) + '.0') text1.insert(str(j) + '.0', ' '.join(customerList) + '\n') text1.update() output.close() phant.quit()
documents = [] # loop through each page of the tutorial calling the already declared functions # on them while True: parent = get_page(page) get_next_page(parent) html = remove_unwanted(parent) # create an html instance html_instance = HTML(string=html) # call weasyprint's render method on the html instance to obtain in # return an instance of the Document class which is stored in the doc object doc = html_instance.render() # append every consecutive doc object to the documents list # that was created earlier. documents.append(doc) # print the url of the current page to the console, this is solely # for debugging and has no effect on the script print(page) # let the loop sleep for about 3secs before sending another request to # to the server, this helps to prevent overloading the server from our end time.sleep(3) # end loop when you get to your desired end-page if page == 'https://www.w3schools.com/python/python_mysql_getstarted.asp':
def constructSvg(procSerial): """ Construct a SVG image out of a processed, dashboard builder serialized state. Args: procSerial: A list representing the dashboard state to be exported. Each item in the list is a dictonary with a `itemType` field, detailing what sort of item is to be drawn. The item types that are drawn so far are 'ChartItem's, 'TitleItem's and 'CommentItem's. Returns: A svg string representing the image. """ svgHeight, svgWidth = _getSize(procSerial) draw = svgwrite.Drawing(size=(svgWidth, svgHeight)) drawHead, drawTail = draw.tostring()[0:-6], draw.tostring()[-6:] drawBody = "" for dashItem in procSerial: position = { k: v * GRID_SIZE for k, v in dashItem['position'].iteritems() } w, h, x, y = position['width'], position['height'], position[ 'left'], position['top'] g = svgwrite.container.Group() g.translate(x, ty=y) if dashItem['itemType'] in JS_ITEMS: for item in dashItem['items']: t, attrs = item['type'], item['attr'] if t == 'rect': svg, attrs = _svgRect(draw, attrs) elif t == 'circle': svg, attrs = _svgCirc(draw, attrs) elif t == 'path': svg, attrs = _svgPath(draw, attrs) elif t == 'text': svg, attrs = _svgText(draw, attrs) g.add(svg) elif dashItem['itemType'] == 'TitleItem': titleSvg, attrs = _svgText( draw, { 'x': 0, 'y': 0, 'text': dashItem['textContent'], 'lineHeight': dashItem.get('lineHeight', 10), 'font-size': '1.35em', 'font-family': 'helvetica', 'font-weight': 'bold' }) g.add(titleSvg) elif dashItem['itemType'] == 'CommentItem': bgSvg, attrs = _svgRect( draw, { 'x': COMMENT_PADDING, 'y': COMMENT_PADDING, 'width': w - COMMENT_PADDING, 'height': h - COMMENT_PADDING, 'fill': '#fff8b6', 'stroke': '#eae1a0', 'stroke-width': 1 }) g.add(bgSvg) authorSvg, attrs = _svgText( draw, { 'x': COMMENT_PADDING + AUTHOR_PADDING, 'y': COMMENT_PADDING + 2 * AUTHOR_PADDING, 'text': dashItem['author'], 'lineHeight': dashItem['lineHeight'], 'font-weight': 600, 'font-size': '1em', 'fill': '#8c8c8c', 'clip': 'rect(10,10,{width},{height})'.format( width=w - COMMENT_PADDING, height=h - COMMENT_PADDING), 'font-family': 'helvetica' }) g.add(authorSvg) textSvg, attrs = _svgText( draw, { 'x': COMMENT_PADDING + AUTHOR_PADDING, 'y': COMMENT_PADDING + AUTHOR_PADDING + AUTHOR_HEIGHT, 'text': dashItem['textContent'], 'lineHeight': dashItem['lineHeight'], 'font-weight': 'normal', 'font-size': '1em', 'font-family': 'helvetica' }) g.add(textSvg) elif dashItem['itemType'] == 'PivotTableItem': from weasyprint import HTML, CSS dashItem['html'] = dashItem['html']\ .replace('align="right"', 'class="alignright"')\ .replace('align="center"', 'class="aligncenter"') html = HTML(string=dashItem['html']) wpx, hpx = '{width}px'.format(width=w), '{height}px'.format( height=h) css = CSS(string=""" @page { margin: 0; padding: 0; size: %s %s; } table, th, td, tr { border: 1px solid black; border-collapse: collapse; border-spacing: 0; padding: 0; margin: 0; font-weight: normal; background-color: white; } table { width: %s; height: %s; } .alignright { text-align: right; } .aligncenter { text-align: center; } """ % (wpx, hpx, wpx, hpx)) page = html.render(stylesheets=[css]).pages[0] with tmpfile() as tmp: import cairocffi as cairo surface = cairo.SVGSurface(tmp, x + page.width, y + page.height) page.paint(cairo.Context(surface), left_x=x, top_y=y) surface.finish() tmp.seek(0) for line in tmp: if re.match(r'<(?:xml|(/)?svg).*>', line) is None: drawBody += line drawBody = drawBody.rstrip() if dashItem['itemType'] != "PivotTableItem": drawBody += g.tostring() return drawHead + drawBody + drawTail
def asiento_contable_con_comprobante_generar_tirilla(asiento_contable_id: int): asiento_contable = AsientoContable.objects.get(pk=asiento_contable_id) comprobante_contable = asiento_contable.tipo_comprobante_bancario_empresa empresa = comprobante_contable.empresa context = { "nota": asiento_contable.nota, "fecha": asiento_contable.fecha, "concepto": asiento_contable.concepto, "nro_comprobante": asiento_contable.nro_comprobante, "tercero_nombre": asiento_contable.tercero.full_name_proxy if asiento_contable.tercero else None, "usuario": asiento_contable.usuario.get_full_name() if asiento_contable.usuario else None, "nit_empresa": empresa.nit if empresa else None, "nombre_empresa": empresa.nombre if empresa else None, "pais": comprobante_contable.pais_emision if comprobante_contable else None, "ciudad": comprobante_contable.ciudad_emision if comprobante_contable else None, "telefono": comprobante_contable.telefono_emision if comprobante_contable else None, "direccion": comprobante_contable.direccion_emision if comprobante_contable else None, "fecha_autorizacion": comprobante_contable.fecha_autorizacion if comprobante_contable else None, "rango_superior_numeracion": comprobante_contable.rango_superior_numeracion if comprobante_contable else None, "rango_inferior_numeracion": comprobante_contable.rango_inferior_numeracion if comprobante_contable else None, "numero_autorizacion": comprobante_contable.numero_autorizacion if comprobante_contable else None, "descripcion_comprobante": comprobante_contable.tipo_comprobante.descripcion if comprobante_contable else None, "codigo_comprobante": comprobante_contable.tipo_comprobante.codigo_comprobante, "valor": asiento_contable.total_credito } html_get_template = get_template( 'comprobantes_contables/comprobante_contable.html').render(context) html = HTML(string=html_get_template) width = '80mm' height = '10cm' size = 'size: %s %s' % (width, height) margin = 'margin: 0.8cm 0.8cm 0.8cm 0.8cm' css_string = '@page {text-align: justify; font-family: Arial;font-size: 0.6rem;%s;%s}' % ( size, margin) main_doc = html.render(stylesheets=[CSS(string=css_string)]) return main_doc
def constructSvg(procSerial): """ Construct a SVG image out of a processed, dashboard builder serialized state. Args: procSerial: A list representing the dashboard state to be exported. Each item in the list is a dictonary with a `itemType` field, detailing what sort of item is to be drawn. The item types that are drawn so far are 'ChartItem's, 'TitleItem's and 'CommentItem's. Returns: A svg string representing the image. """ svgHeight, svgWidth = _getSize(procSerial) draw = svgwrite.Drawing(size=(svgWidth, svgHeight)) drawHead, drawTail = draw.tostring()[0:-6], draw.tostring()[-6:] drawBody = "" for dashItem in procSerial: position = {k: v * GRID_SIZE for k, v in dashItem['position'].iteritems()} w, h, x, y = position['width'], position['height'], position['left'], position['top'] g = svgwrite.container.Group() g.translate(x, ty=y) if dashItem['itemType'] in JS_ITEMS: for item in dashItem['items']: t, attrs = item['type'], item['attr'] if t == 'rect': svg, attrs = _svgRect(draw, attrs) elif t == 'circle': svg, attrs = _svgCirc(draw, attrs) elif t == 'path': svg, attrs = _svgPath(draw, attrs) elif t == 'text': svg, attrs = _svgText(draw, attrs) g.add(svg) elif dashItem['itemType'] == 'TitleItem': titleSvg, attrs = _svgText(draw, { 'x': 0 , 'y': 0 , 'text': dashItem['textContent'] , 'lineHeight': dashItem.get('lineHeight', 10) , 'font-size': '1.35em' , 'font-family': 'helvetica' , 'font-weight': 'bold' }) g.add(titleSvg) elif dashItem['itemType'] == 'CommentItem': bgSvg, attrs = _svgRect(draw, { 'x': COMMENT_PADDING , 'y': COMMENT_PADDING , 'width': w - COMMENT_PADDING , 'height': h - COMMENT_PADDING , 'fill': '#fff8b6' , 'stroke': '#eae1a0' , 'stroke-width': 1 }) g.add(bgSvg) authorSvg, attrs = _svgText(draw, { 'x': COMMENT_PADDING + AUTHOR_PADDING , 'y': COMMENT_PADDING + 2 * AUTHOR_PADDING , 'text': dashItem['author'] , 'lineHeight': dashItem['lineHeight'] , 'font-weight': 600 , 'font-size': '1em' , 'fill': '#8c8c8c' , 'clip': 'rect(10,10,{width},{height})'.format( width = w - COMMENT_PADDING , height = h - COMMENT_PADDING) , 'font-family': 'helvetica' }) g.add(authorSvg) textSvg, attrs = _svgText(draw, { 'x': COMMENT_PADDING + AUTHOR_PADDING , 'y': COMMENT_PADDING + AUTHOR_PADDING + AUTHOR_HEIGHT , 'text': dashItem['textContent'] , 'lineHeight': dashItem['lineHeight'] , 'font-weight': 'normal' , 'font-size': '1em' , 'font-family': 'helvetica' }) g.add(textSvg) elif dashItem['itemType'] == 'PivotTableItem': from weasyprint import HTML, CSS dashItem['html'] = dashItem['html']\ .replace('align="right"', 'class="alignright"')\ .replace('align="center"', 'class="aligncenter"') html = HTML(string=dashItem['html']) wpx, hpx = '{width}px'.format(width = w), '{height}px'.format(height = h) css = CSS(string=""" @page { margin: 0; padding: 0; size: %s %s; } table, th, td, tr { border: 1px solid black; border-collapse: collapse; border-spacing: 0; padding: 0; margin: 0; font-weight: normal; background-color: white; } table { width: %s; height: %s; } .alignright { text-align: right; } .aligncenter { text-align: center; } """ % (wpx, hpx, wpx, hpx)) page = html.render(stylesheets=[css]).pages[0] with tmpfile() as tmp: import cairocffi as cairo surface = cairo.SVGSurface(tmp, x + page.width, y + page.height) page.paint(cairo.Context(surface), left_x=x, top_y=y) surface.finish() tmp.seek(0) for line in tmp: if re.match(r'<(?:xml|(/)?svg).*>', line) is None: drawBody += line drawBody = drawBody.rstrip() if dashItem['itemType'] != "PivotTableItem": drawBody += g.tostring() return drawHead + drawBody + drawTail