Форум сайта python.su
4
Необходимо сгенерировать PDF отчёт состоящий из скриншотов. Каждый скриншот должен быть на отдельной странице, внизу должно быть название страницы. Была выбрана библиотека pisa - позволяет использовать html для оформления шаблона. К сожалению исходные скриншоты могут быть разного размера, поэтому не получается выполнить требование один скриншот на страницу( он не обязан заполнять всю страницу, внизу может быть пустое место ). Как сделать с помощью html или css чтобы нижний блок под скриншотом заполнял оставшееся место страницы( Страницы формата А4 )
Вот рабочий код (все хранилось в отдельных модулях но для форума я свёл в один файлик) :
# -*- coding: utf-8 -*- import re import sys import os from datetime import date, timedelta, datetime import requests import lxml.html import codecs import ho.pisa as pisa header = u''' <html> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <head> <style> @page { margin: 40px; margin-left: 60px; margin-bottom: 70px; @frame footer { -pdf-frame-content: footerContent; bottom: 10px; margin-left: 60px; margin-right: 40px; height: 40px; } } @font-face { font-family: courier; src: url(fonts/Courier_New.ttf); } @font-face { font-family: courier; src: url(fonts/Courier_Bold.ttf); font-weight: bold; } @font-face { font-family: courier; src: url(fonts/Courier_Bold_Italic.ttf); font-weight: bold; font-style: italic; } @font-face { font-family: courier; src: url(fonts/Courier_Italic.ttf); font-style: italic; } @font-face { font-family: verdana; src: url(fonts/Verdana.ttf); } @font-face { font-family: verdana; src: url(fonts/Verdana_Bold.ttf); font-weight: bold; } @font-face { font-family: verdana; src: url(fonts/Verdana_Italic.ttf); font-style: italic; } @font-face { font-family: verdana; src: url(fonts/Verdana_Bold_Italic.ttf); font-style: italic; font-weight: bold; } img { font-family: sans; } body, div { font-family: verdana; font-size: 14px; color:#000; background:#fff; } a[href] { color: #6da3bd; } a[name] { color: #000000; font-size: 150%; text-decoration:none} fieldset {border:0 solid transparent;} input, select, textarea { font-size: 100%; font-family: verdana; } blockquote { border-left:2px solid #bbb; margin: .83em 10; padding-left:15px; clear: both; } ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,body,html,blockquote,fieldset,dl,dt,dd,caption {margin:0; padding:0;} ul,ol {list-style: none;} pre,code {font-size: 1em;} h1, h2, h3, h4, h5, h6 { color:#999999; font-family: verdana; font-weight:normal; margin:0 0 0 0; padding:0; } h1 { font-size:162.5%; letter-spacing:-1px; margin-bottom:0.7em; } h2 { font-size:150%; } h3 { font-size: 137.5%; } h4 { font-size: 120%; } h5 { font-size: 110%; } h6 { font-size: 100%; } pre { font-size: 80%; } </style> </head> <body> <div align="center"><img src="TEMP/header.png"></div>''' footer = u''' <div id="footerContent" align="right"> <hr> Страница #<pdf:pagenumber> </div> </body> </html> ''' def go(content, filename): print '\n Prepare PDF...\n' content = header + content + footer #pisa.showLogging() pisa.CreatePDF(content.encode('UTF-8'), file(filename, 'wb'), raise_exception=False) #f = open('1.html', 'w') #f.write(topic) #f.close() content = '' directory = './screenshots' files = os.listdir(directory) images = filter(lambda x: x.endswith('.png'), files) for image in images: print image content += '<div align="center"><img src="./screenshots/' + image + '"></div><div align="center"><img src="w.png"></div>' go(content, 'test.pdf')
Офлайн
4
Написал рабочее решение, если кому интересно завтра выложу его
Офлайн
63
Интересно. Давайте. Пригодится.
Я бы искал решение через odfpy, но если есть готовое, почему бы не воспользоваться.
Офлайн
4
Это грубый прототип, т.к. сами скриншоты ещё не поступили. Но в случае чего его можно легко исправить. Использовал код из примеров отсюда https://github.com/chrisglass/xhtml2pdf/blob/master/doc/usage.rst . Одной страницы на листе добиваемся генерацией через html прозрачной картинки которая будет заполнять оставшуюся высоту страницы в зависимости от разрешения вставляемого скриншота.
# -*- coding: utf-8 -*- from xhtml2pdf import pisa # import python module import os import Image sourceHtml = '' directory = './screenshots' files = os.listdir(directory) images = filter(lambda x: x.endswith('.png'), files) first = u""" <html> <head> <style> @page { @frame header_frame { -pdf-frame-content: header_content; left: 100pt; width: 557pt; top: 0pt; height: 100pt; } @frame content_frame { left: 50pt; width: 512pt; top: 90pt; height: 632pt; } @frame footer_frame { -pdf-frame-content: footer_content; left: 250pt; width: 512pt; top: 772pt; height: 20pt; } } @font-face { font-family: courier; src: url(fonts/Courier_New.ttf); } @font-face { font-family: courier; src: url(fonts/Courier_Bold.ttf); font-weight: bold; } @font-face { font-family: courier; src: url(fonts/Courier_Bold_Italic.ttf); font-weight: bold; font-style: italic; } @font-face { font-family: courier; src: url(fonts/Courier_Italic.ttf); font-style: italic; } @font-face { font-family: verdana; src: url(fonts/Verdana.ttf); } @font-face { font-family: verdana; src: url(fonts/Verdana_Bold.ttf); font-weight: bold; } @font-face { font-family: verdana; src: url(fonts/Verdana_Italic.ttf); font-style: italic; } @font-face { font-family: verdana; src: url(fonts/Verdana_Bold_Italic.ttf); font-style: italic; font-weight: bold; } img { font-family: sans; } body, div { font-family: verdana; font-size: 14px; color:#000; background:#fff; } </style> </head> <body> <!-- Content for Static Frame 'header_frame' --> <div id="header_content"><img src="logo.png"></div> <!-- Content for Static Frame 'footer_frame' --> <div id="footer_content"> Страница <pdf:pagenumber> из <pdf:pagecount> </div> <img src= """ middle = u""""><br/> <img src="mini.png" width="680" height=" """ end = u""" "> </body> </html> """ for image in images: print image parse_height = 0 img = Image.open(directory+'/'+image) width, height = img.size if width > 512 : new_height = height / (width/512) if new_height < 632 : parse_height = 632 - new_height sourceHtml += first + '"' + directory + '/' + image + middle + str(parse_height) + end outputFilename = "test.pdf" # Utility function def convertHtmlToPdf(sourceHtml, outputFilename): # open output file for writing (truncated binary) resultFile = open(outputFilename, "w+b") # convert HTML to PDF pisaStatus = pisa.CreatePDF( sourceHtml.encode('UTF-8'), # the HTML to convert dest=resultFile) # file handle to recieve result # close output file resultFile.close() # close output file # return True on success and False on errors return pisaStatus.err # Main program if __name__=="__main__": pisa.showLogging() convertHtmlToPdf(sourceHtml, outputFilename)
Офлайн
4
а ещё есть офигенный пример с хабра http://habrahabr.ru/post/111411/ - если кто то хочет начать работать с pisa то в этом рабочем примере красиво используются почти все функции
Офлайн