I currently am creating a perfectly good PDF. there is nothing technically wrong with it. However, the TOC is ugly.
The TOC is generated via xsl which is passed through jinja2 for simple details to the top section of the page. I have modified the XSL to match the client's branding and design precisely. However, the list keeps growing in height.
Here is the current result (sorry to blur the text) you can see the toc picks up at the right spot on the new page, but there seems to be no way to apply a top margin to the new page:
The code:
Here is the xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:outline="http://wkhtmltopdf.org/outline"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
indent="yes" />
<xsl:template match="outline:outline">
<html>
<head>
<title>Table of Contents</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
body{
background-color: #fff;
margin-left: 0px;
margin-top: 0px;
color:#1e1e1e;
font-family: arial, verdana,sans-serif;
font-size: 90px;
}
.contentSection{
position:relative;
height:3200px;
width:6100px;
}
.profile{
position:absolute;
display:inline-block;
top:200px !important;
}
h1 {
text-align: left;
font-size: 70px;
font-family: arial;
color: #ef882d;
}
li {
border-bottom: 1px dashed rgb(45,117,183);
}
span {float: right;}
li {
list-style: none;
margin-top:30px;
}
ul {
font-size: 70px;
font-family: arial;
color:#2d75b7;
}
ul ul {font-size: 80%; padding-top:0px;}
ul {padding-left: 0em; padding-top:0px;}
ul ul {padding-left: 1em; padding-top:0px;}
a {text-decoration:none; color: color:#2d75b7;}
#topper{
width:100%;
border-bottom:8px solid #ef882d;
}
#title{
position:absolute;
top:60px;
font-size:60px;
left:150px;
color:#666666;
}
h1, h2{
font-size:60px;
-webkit-margin-before: 0px;
-webkit-margin-after: 0px;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
}
#profile{
position:static;
-webkit-border-top-left-radius: 40px;
-webkit-border-bottom-left-radius: 40px;
-moz-border-radius-topleft: 40px;
-moz-border-radius-bottomleft: 40px;
border-top-left-radius: 40px;
border-bottom-left-radius: 40px;
right:-540px;
background-color: #2d75b7;
padding:4px;
padding-left:60px;
padding-right:250px;
color:#fff;
display:inline-block;
margin-top:200px;
float:right;
}
#room{
padding-top: 200px;
padding-left: 150px;
display:inline-block;
}
#section{
padding-left: 150px;
color: #ef882d;
text-transform: uppercase;
font-size:60px;
font-weight: bold;
display:inline-block;
margin-top: 30px;
margin-bottom: 5px;
}
#area{
padding-left: 150px;
font-size:60px;
color:#2d75b7;
margin-top: 15px;
}
#dims{
padding-left: 150px;
font-size:60px;
color:#2d75b7;
margin-top: 15px;
}
#toc{
width:50%;
margin-top:150px;
margin-left:300px;
}
</style>
<script>
var value = {{profile|e}};
</script>
</head>
<body>
<div class="contentSection">
<div id="title">A title here</div>
<div id="topper">
<div id="profile" class="profile">{{profile|e}}</div>
<div id="room"> {{profile|e}} </div>
<div id="area"> Revision Date </div>
<div id="dims"> {{area|e}} </div>
<div id="section">Table of Contents</div>
</div>
<div id="toc">
<ul><xsl:apply-templates select="outline:item/outline:item"/></ul>
</div>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="outline:item">
<! begin LI>
<li>
<xsl:if test="#title!=''">
<div>
<a>
<xsl:if test="#link">
<xsl:attribute name="href"><xsl:value-of select="#link"/> .
</xsl:attribute>
</xsl:if>
<xsl:if test="#backLink">
<xsl:attribute name="name"><xsl:value-of select="#backLink"/> . </xsl:attribute>
</xsl:if>
<xsl:value-of select="#title" />
</a>
<span>
<xsl:value-of select="#page" />
</span>
</div>
</xsl:if>
<ul>
<xsl:comment>added to prevent self-closing tags in QtXmlPatterns</xsl:comment>
<xsl:apply-templates select="outline:item"/>
</ul>
</li>
</xsl:template>
</xsl:stylesheet>
I have dealt with content overflows in other areas of the PDF using traditional HTML, JavaScript, and a document ready flag. The TOC however requires an XSL file instead.
I tried do this with nth-child css nth-child is ignored.
The question:
*Is there a way within wkhtmltopdf or python pdf-kit to deal with page breaks in the TOC specifically, and place a better margin top on the new page? is there a way to supply a TOC as a traditional html page so that I can do this with javaScript instead? *
Code review
I made a quick code review in your XSL (and CSS) file.
Even if it doesn’t solve your problem, it help reproducing and understanding it.
Here is my comments:
Your XSL has a typo: <! begin LI> is not a valid XML tab. Is it a comment?
I prefer using the concat() XPath function to append characters directly. Because, if you re-indent your code, you may introduce extra whitespaces.
So, I replaced:
<xsl:attribute name="href"><xsl:value-of select="#link"/> . </xsl:attribute>
By:
<xsl:attribute name="href">
<xsl:value-of select="concat(#link, ' . ')"/>
</xsl:attribute>
I added a xs:if to prevent generating an empty <ul> if it is not necessary:
<xsl:if test="count(outline:item)">
<ul>
<xsl:comment>added to prevent self-closing tags in QtXmlPatterns</xsl:comment>
<xsl:apply-templates select="outline:item"/>
</ul>
</xsl:if>
I also fixed duplicate or mal-formed CSS entries, I replaced:
li {
border-bottom: 1px dashed rgb(45, 117, 183);
}
span {
float: right;
}
li {
list-style: none;
margin-top: 30px;
}
ul ul {font-size: 80%; padding-top:0px;}
ul {padding-left: 0em; padding-top:0px;}
ul ul {padding-left: 1em; padding-top:0px;}
a {text-decoration:none; color: color:#2d75b7;}
by:
span {
float: right;
}
li {
list-style: none;
margin-top: 30px;
border-bottom: 1px dashed rgb(45, 117, 183);
}
ul {
font-size: 70px;
font-family: arial;
color: #2d75b7;
}
ul ul {
font-size: 80%;
padding-left: 1em;
padding-top: 0px;
}
a {
text-decoration: none;
color: #2d75b7;
}
If you target XHTML, the <style> tag has a mandatory type attribute. Same remark for the <script> attribute.
<style type="text/css">...</style>
<script type="text/javascript">...</script>
Reproducing the problem
It was a little hard to reproduce your bug, because of a lack of information. So I guess it.
First, I create a sample TOC file, which look like this:
outline.xml
<?xml version="1.0" encoding="UTF-8"?>
<outline xmlns="http://wkhtmltopdf.org/outline">
<item>
<item title="Lorem ipsum dolor sit amet, consectetur adipiscing elit." page="2"/>
<item title="Cras at odio ultrices, elementum leo at, facilisis nibh." page="8"/>
<item title="Vestibulum sed libero bibendum, varius massa vitae, dictum arcu." page="19"/>
...
<item title="Sed semper augue quis enim varius viverra." page="467"/>
</item>
</outline>
This file contains 70 items so that I can see the page breaks.
To build the HTML and PDF I used your (fixed) XSL file and run pdfkit:
import io
import os
import pdfkit
from lxml import etree
HERE = os.path.dirname(__file__)
def layout(src_path, dst_path):
# load the XSL
xsl_path = os.path.join(HERE, "layout.xsl")
xsl_tree = etree.parse(xsl_path)
# load the XML source
src_tree = etree.parse(src_path)
# transform
transformer = etree.XSLT(xsl_tree)
dst_tree = transformer.apply(src_tree)
# write the result
with io.open(dst_path, mode="wb") as f:
f.write(etree.tostring(dst_tree, encoding="utf-8", method="html"))
if __name__ == '__main__':
layout(os.path.join(HERE, "outline.xml"), os.path.join(HERE, "outline.html"))
pdfkit.from_file(os.path.join(HERE, "outline.html"),
os.path.join(HERE, "outline.pdf"),
options={'page-size': 'A1', 'orientation': 'landscape'})
note: your page size looks very huge…
Solution
You are right, wkhtmltopdf doesn't take into account the margin in your CSS:
li {
list-style: none;
border-bottom: 1px dashed rgb(45, 117, 183);
margin-top: 30px; # <-- not working after page break
}
This is a normal behavior, consider for instance the header paragraphs (h1, h2, etc.).
A header can have a top margin in order to add white space between a paragraph and the following header,
but, if the header starts a new page we want to get rid of the margin, and have the heading touching to top margin of the page.
For your TOC, there is a solution. You can use padding (instead of margin):
li {
border-bottom: 1px dashed rgb(45, 117, 183);
list-style: none;
padding-top: 30px;
}
Actually, the TOC content (#toc element) is fixed:
#toc {
width: 50%;
margin-top: 150px;
margin-left: 300px;
}
So, you can reduce the margin-top to match your need, for instance:
#toc {
width: 50%;
margin-top: 120px;
margin-left: 300px;
}
Related
I'm making an API REST request using Python. And I encountered the following html result that says "Service - Endpoint not found. Please see the service help page for constructing valid requests to the service"
How can I fix this issue?
Note: This API can help determine whether an individual address is up to date by inputting individual address, first name, last name, etc.
Python query
import requests
import json
url = 'https://smartmover.melissadata.net/v3/WEB/SmartMover/doSmartMover/'
payload = {'t': '1353', 'id': 'sw38hs47u', 'jobid': '1', 'act': 'NCOA, CCOA', 'cols': 'TransmissionResults,TransmissionReference, Version, TotalRecords,CASSReportLink,NCOAReportLink,Records,AddressExtras,AddressKey,AddressLine1,AddressLine2,AddressTypeCode,BaseMelissaAddressKey,CarrierRoute,City,CityAbbreviation,CompanyName,CountryCode,CountryName,DeliveryIndicator,DeliveryPointCheckDigit,DeliveryPointCode,MelissaAddressKey,MoveEffectiveDate,MoveTypeCode,PostalCode,RecordID,Results,State,StateName,Urbanization', 'opt': 'ProcessingType: Standard', 'List': 'test', 'full': 'PATEL MANISH', 'first':'MANISH','last':'PATEL', 'a1':'1600 S 5TH ST', 'a2':'1600 S 5TH ST', 'city':'Austin', 'state': 'TX', 'postal': '78704', 'ctry': 'USA'}
response = requests.get(url, params=payload)
print (response.text)
Result
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Service</title>
<style>BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; } #content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; } A:link { color: #336699; font-weight: bold; text-decoration: underline; } A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; } A:active { color: #336699; font-weight: bold; text-decoration: underline; } .heading1 { background-color: #003366; border-bottom: #336699 6px solid; color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal;margin: 0em 0em 10px -20px; padding-bottom: 8px; padding-left: 30px;padding-top: 16px;} pre { font-size:small; background-color: #e5e5cc; padding: 5px; font-family: Courier New; margin-top: 0px; border: 1px #f0f0e0 solid; white-space: pre-wrap; white-space: -pre-wrap; word-wrap: break-word; } table { border-collapse: collapse; border-spacing: 0px; font-family: Verdana;} table th { border-right: 2px white solid; border-bottom: 2px white solid; font-weight: bold; background-color: #cecf9c;} table td { border-right: 2px white solid; border-bottom: 2px white solid; background-color: #e5e5cc;}</style>
</head>
<body>
<div id="content">
<p class="heading1">Service</p>
<p xmlns="">Endpoint not found. Please see the <a rel="help-page" href="https://smartmover.melissadata.net/v3/WEB/SmartMover/help">service help page</a> for constructing valid requests to the service.</p>
</div>
</body>
</html>
[Finished in 0.9s]
Remove the / at the end of the url:
import requests
import json
url = 'https://smartmover.melissadata.net/v3/WEB/SmartMover/doSmartMover' # <<<
payload = {'t': '1353', 'id': 'sw38hs47u', 'jobid': '1', ...}
response = requests.get(
url, params=payload,
headers={'Content-Type': 'application/json'} # Using JSON here for readability in the response
)
print (response.text)
Output:
{
"CASSReportLink": "",
"NCOAReportLink": "",
"Records": [],
"TotalRecords": "",
"TransmissionReference": "1353",
"TransmissionResults": "SE20",
"Version": "4.0.4.48"
}
I'm trying to use the findChildren() function. I basically want all the <p> under a particular <h3> tag. I'm trying a simple amount of code but the set children. I'm getting back is empty. h3 returns the correct line (see print(h3) comment) and the print(type(children)) prints type: <class 'bs4.element.ResultSet'>. Please tell me what I'm doing wrong.
soup = BeautifulSoup(contents, 'html.parser')
h3 = soup.find('h3', text=re.compile('chapter', re.IGNORECASE))
print(h3) #result prints <h3 style="text-align: center;">CHAPTER ONE - STEPHANUS GRAYLAND</h3>
children = h3.findChildren('p')
print(type(children)) #returns type: <class 'bs4.element.ResultSet'>
I also tried h3.findChildren('p', Recursive=True) and children = h3.findChildren(Recursive=True). Which also come back empty.
Here's the section of HTML I'm trying to grab:
<h3 style="text-align: center;">CHAPTER ONE - STEPHANUS GRAYLAND</h3>
<p dir="ltr" style="line-height: 1.15; margin-top: 0pt; margin-bottom: 0pt;">
<span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;">Stephanus Grayland did not try to hide his smile of satisfaction . He had “eaten” lunch, but now, he sensed, he would truly </span>
<span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">feast</span>
<span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;">.</span>
</p>
<p></p>
Thanks to those who responded. My problem is that <h3> and the sub <p>s are siblings not parent/child. I think these posts are what I'm after code-wise but my comment above remains. http://stackoverflow.com/questions/51571609/… and http://stackoverflow.com/questions/51852588/
In the sample you provided, the h3 node has no children. All of the p nodes are outside of that scope.
If you wrap your contents in a div (say) then you can see you're using the right technique
>>> soup = BeautifulSoup('<div>' + contents + '</div>', 'html.parser')
>>> div = soup.find('div')
>>> div.findChildren('p')
[<p dir="ltr" style="line-height: 1.15; margin-top: 0pt; margin-bottom: 0pt;"><span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;">Stephanus Grayland did not try to hide his smile of satisfaction . He had “eaten” lunch, but now, he sensed, he would truly </span><span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">feast</span><span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;">.</span></p>, <p> </p>]
>>>
Edit
As you mention in your comments above, the h3 and p nodes are siblings in the content you've supplied. I'm not sure it makes sense to have p elements that are children of h3, but if you did it would look like
<h3>
This content is within the h3 tag
<p>this is a child of h3</p>
<p>another child</p>
</h3>
<p>this is not a child of h3 as it is after the h3 close tag</p>
It's not really clear what the conditions for selecting p nodes in your example content should be - a simple soup.find('p') would return all of those tags, but I suspect you need to limit it in some way to prevent other content from being included. Can you elaborate? You possibly just want something like:
>>> soup = BeautifulSoup(content, 'html.parser')
>>> h3 = soup.find('h3')
>>> h3.find_next_sibling('p')
<p dir="ltr" style="line-height: 1.15; margin-top: 0pt; margin-bottom: 0pt;">
<span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;">Stephanus Grayland did not try to hide his smile of satisfaction . He had “eaten” lunch, but now, he sensed, he would truly </span>
<span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">feast</span>
<span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;">.</span>
</p>
Thank you for your patience. I had to figure out how to get the html structure, prettify the html and write to a file to see the relationships better, etc. The pages I need to process (I didn't write them) have a structure as below. After building the bs4 structure, I figured out my desired content starts at the <article..> tag and ends at the beginning of the next <script...> code here</<script> <h3>Comments</h3>. I'm not sure how to terminate a search between two different tags. I was able to grab EVERYTHING between an <h3> tag and the next <h3> tag. But that pulls the <script> section which I don't want. Thanks again for continuing help! -Meghan
....
<div id="rt-main" class="sa3-mb9">
<div class="rt-container">
<div class="rt-grid-9 rt-push-3">
<div class="rt-block">
<div id="rt-mainbody">
<div class="component-content">
<article class="item-pageDarkening">
<h3 style="text-align: center;">CHAPTER ONE - STEPHANUS GRAYLAND</h3>
<p> </p>
<p style="line-height: 1.15; margin-top: 0pt; margin-bottom: 0pt;" dir="ltr"><span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">text.. ż/span></p>
<p> </p>
<p style="line-height: 1.15; margin-top: 0pt; margin-bottom: 0pt;" dir="ltr"><span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;">text here</span><span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"></span><span style="font-size: 16px; font-family: 'Times New Roman'; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;">.</span></p>
<p> </p>
<p>dljlg</p>
<span></span>
<p>dljlg</p>
<span></span>
<p style="line-height: 1.15; margin-top: 0pt; margin-bottom: 0pt;" dir="ltr"><em><span style="font-size: 16px; font-family: 'arial black', 'avant garde'; background-color: transparent; vertical-align: baseline; white-space: pre-wrap;"> </span></em></p>
<script type='text/javascript'>
Komento.ready(function($) {
// declare master namespace variable for shared values
Komento.component = "com_content";
Komento.cid = "1211";
Komento.contentLink = "...";
Komento.sort = "latest";
Komento.loadedCount = parseInt(10);
Komento.totalCount = parseInt(56);
if( Komento.options.konfig.enable_shorten_link == 0 ) {
Komento.shortenLink = Komento.contentLink;
}
});
</script>
<div id="section-kmt" class="theme-kuro">
<script type="text/javascript">
Komento.require()
.library('dialog')
.script(
'komento.language',
'komento.common',
'komento.commentform'
)
.done(function($) {
if($('.commentForm').exists()) {
Komento.options.element.form = new Komento.Controller.CommentForm($('.commentForm'));
Komento.options.element.form.kmt = Komento.options.element;
}
});
</script>
<div id="kmt-form" class="commentForm kmt-form clearfix">
<a class="addCommentButton kmt-form-addbutton" href="javascript:void(0);"><b>Add comment</b></a>
<div class="formArea kmt-form-area hidden">
<h3 class="kmt-title">Leave your comments</h3>
I am using google maps which has a basic form for the user to fill in his details. On clicking submit the form details are suppose to get stored in the MySQL table that I have created.
I am using apache that is already pre-installed on my mac.
I have downloaded MySQL and its running fine. I have created the table with the required columns in it.
I am using PyCharm Community Edition for running my python scripts.
My map.html file (the one which has the google map with the form) is running fine on localhost.
However, on clicking submit I get the following error :
Not Found
The requested URL /Library/WebServer/CGI-Executables/processing.py was not found on this server.
My map.html file is in Library/WebServer/Documents/
#map.html file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta charset="utf-8" />
<title>MAPS</title>
<style>
#map {
width: 100%;
height: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#description {
font-family: Calibri;
font-size: 15px;
font-weight: 300;
}
#infowindow-content .title {
display: none;
}
#map #infowindow-content {
display: none;
}
.pac-card {
margin: 10px 10px 0 0;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
background-color: #fff;
font-family: Calibri;
}
#pac-container {
padding-bottom: 12px;
margin-right: 12px;
}
.pac-controls {
display: inline-block;
padding: 5px 11px;
}
.pac-controls label {
font-family: Calibri;
font-size: 16px;
font-weight: 400;
}
#pac-input {
background-color: #fff;
font-family: Calibri;
font-size: 15px;
font-weight: 400;
margin-left: 12px;
padding: 8px 12px;
text-overflow: ellipsis;
width: 400px;
border: 1px solid #ccc;
}
#pac-input:focus {
border-color: #4d90fe;
}
#title {
color: #fff;
background-color: #4d90fe;
font-size: 25px;
font-weight: 400;
padding: 6px 12px;
}
#target {
width: 345px;
}
#form
{
display: none;
}
#heading {
text-align: center;
color: #003366;
font-size: 30px;
font-family: Calibri;
padding: 8px 12px;
}
label.field {
text-align: left;
font-weight: bolder;
font-size: 16px;
font-family: Calibri;
}
input[type=text], input[type=email], input[type=number], select {
font-family: Calibri;
font-size: 16px;
font-weight: bolder;
padding: 8px 12px;
width: 100%;
margin: 8px 0;
display: inline-block;
border: 1px solid black;
border-radius: 4px;
box-sizing: border-box;
}
input[type=submit] {
font-family: Calibri;
font-size: 16px;
font-weight: bolder;
background-color: white;
color: #00b300;
padding: 8px 12px;
margin: 8px 0;
border: 2px solid #00b300;
border-radius: 4px;
cursor: pointer;
box-sizing: border-box;
}
input[type=submit]:hover {
background-color: #00b300;
color: white;
}
input[type=reset] {
font-family: Calibri;
font-size: 16px;
font-weight: bolder;
background-color: white;
color: #cc0000;
padding: 8px 12px;
margin: 8px 0;
border: 2px solid #cc0000;
border-radius: 4px;
cursor: pointer;
box-sizing: border-box;
}
input[type=reset]:hover {
background-color: #cc0000;
color: white;
}
input[type=text]:focus {
background-color: #f2f2f2;
border-color: #4d90fe;
}
input[type=email]:focus {
background-color: #f2f2f2;
border-color: #4d90fe;
}
input[type=number]:focus {
background-color: #f2f2f2;
border-color: #4d90fe;
}
select:focus {
background-color: #f2f2f2;
border-color: #4d90fe;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC8EAfEQrYVs4c_kMBUQw3tVY8uhEViDCU&libraries=places&callback=initAutocomplete"
async defer>
</script>
</head>
<body>
<div id="map"></div>
<input id="pac-input" class="controls" type="text" placeholder="Search your location..." />
<div id="form">
<form action="Library/WebServer/CGI-Executables/processing.py" method="post">
<p id="heading">PERSONAL INFORMATION</p>
<label class="field" for="fullname"><b>Full Name:</b></label>
<input type="text" name="fullname" placeholder="Eg. Suraj Makhija" size="30" required />
<br />
<br />
<label class="field" for="emailid"><b>E-mail:</b></label>
<input type="email" name="emailid" placeholder="Eg. contact#domain.com" size="30" required />
<br />
<br />
<label class="field" for="mobile"><b>Mobile:</b></label>
<input type="text" name="mobile" placeholder="Eg. 9999999999" maxlength="10" minlength="10" size="30" required />
<br />
<br />
<label class="field" for="gender"><b>Gender:</b></label>
<select name="gender" required>
<option value="male">Male</option>
<option value="female">Female</option>
<option value="other">Other</option>
</select>
<br />
<br />
<label class="field" for="areaofexpertise"><b>Area of Expertise:</b></label>
<input type="text" name="areaofexpertise" placeholder="Eg. Android/iOS Developer" size="30" required />
<br />
<br />
<label class="field" for="yearsofexperience"><b>Years of Experience:</b></label>
<input type="number" name="yearsofexperience" placeholder="Eg. 10" min="0" max="100" required />
<br />
<br />
<p style="text-align: center;">
<input type="submit" value="Submit" />
<input type="reset" value="Clear All" />
</p>
</form>
</div>
<script>
var map;
var iconBase;
var input;
var searchBox;
var markers=[];
var markerArray =[];
var infowindow;
function initAutocomplete() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 20.5937, lng: 78.9629},
zoom: 5,
mapTypeId: 'roadmap',
gestureHandling: 'cooperative'
});
//Declaring infowindow.
infowindow = new google.maps.InfoWindow({
content: document.getElementById('form')
});
// Create the search box and link it to the UI element.
input = document.getElementById('pac-input');
searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
//Creates a marker when the user clicks on a location on the map.
google.maps.event.addListener(map, 'click', function(event) {
addMarker(event.latLng, map);
});
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
}
//Marker function declaration.
function addMarker(location, map) {
// Add the marker at the clicked location.
var iconBase = 'https://maps.google.com/mapfiles/kml/paddle/';
marker = new google.maps.Marker({
draggable: true,
animation: google.maps.Animation.DROP,
position: location,
map: map,
icon: iconBase + 'ylw-blank.png'
});
//Infowindow pops up on clicking the marker.
google.maps.event.addListener(marker, 'click', function() {
document.getElementById('form').style.display='inline-block';
infowindow.open(map, marker);
});
}
</script>
</body>
</html>
My processing.py file (the python script that is used for processing the form data and inserting into the MySQL table) is in Library/WebServer/CGI-Executables/
I haven't made any changes to my httpd.conf file except for adding .py to AddHandler statement.
I am attaching all my files below.
Please help me with this as I have been stuck on this for a very long time now.
Please note that Im using Mac OS Sierra.
Thanks in advance.
#processing.py file
import MySQLdb
import cgi
import cgitb
cgitb.enable()
form = cgi.FieldStorage()
fullname = form.getvalue('fullname', '')
emailid = form.getvalue('emailid', '')
mobile = form.getvalue('mobile', '')
gender = form.getvalue('gender', '')
areaofexpertise = form.getvalue('areaofexpertise', '')
yearsofexperience = form.getvalue('yearsofexperience', '')
db = MySQLdb.connect(host="localhost", user="root", passwd="*****", db="client_database")
cursor = db.cursor()
query = """INSERT INTO client_info (FULL_NAME, EMAIL_ID, MOBILE, GENDER, AREA_OF_EXPERTISE, YEARS_OF_EXPERIENCE)
VALUES (%s, %s, %s, %s, %s, %s)"""
cursor.execute(query, (fullname, emailid, mobile, gender, areaofexpertise, yearsofexperience))
result = cursor.fetchall()
db.commit()
db.close()
I'm creating a PDF with xhtml2pdf using Django. I'm sending that PDF to print, but then they say that some Fonts are not embed. I have a Helvetica font, but I didn't use Helvetica in the PDFs.
Here you have a Screen Shot of the properties of the PDF
As you see, Guilles'ComicFont and TF2Secondary are correclty embbeded, but not with Helvetica.
Here you have my view that generates the PDF:
def generate_pdf(request, book, order):
try:
book = Book.objects.get(pk=int(book))
order = Order.objects.get(identificador=order, cuento=book)
except ObjectDoesNotExist:
raise Http404
data = {}
data = ast.literal_eval(order.datos_variables)
data['order'] = order
template = get_template(order.book.plantilla_html)
html = template.render(Context(data))
url = '/Users/vergere/dev/media/pdfs/%s.pdf' % order.identificador
fichero = open(url, "w+b")
pisaStatus = pisa.CreatePDF(html.encode('utf-8'), dest=fichero, encoding='utf-8')
fichero.seek(0)
fichero.close()
order.url_pdf = '%s.pdf' % order.identificador
order.contador_libro = numero
order.codigo_libro = country_code
order.save()
return HttpResponseRedirect(reverse('order_single', kwargs={'pedido': order.pk}))
And here my HTML:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Background</title>
<style>
#page {
background-image: url("cuento1/img/portada.jpg");
size: 213mm 216mm;
}
#font-face {
font-family: Helvetica;
src: url(pdf_generator/helvetica.ttf);
}
#font-face {
font-family: 'Gilles';
src: url(pdf_generator/cuento1/gilles/gilles.ttf);
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: 'Secondary';
src: url(pdf_generator/cuento1/tf2_secondary/tf2_secondary.ttf);
font-weight: normal;
font-style: normal;
}
* {
box-shadow:none !important;
margin: 0;
padding: 0;
text-shadow: none !important;
font-family: 'Gilles';
}
body{
font-family: 'Gilles';
}
p {
color: #464439;
display: block;
font-weight: normal;
position: absolute;
}
.page-1 p, .page-2 p{
font-family: 'Secondary';
font-size: 40px;
line-height: 1.3em;
position: absolute;
}
</style>
</head>
<body>
<pdf:nextpage name="p1" />
<pdf:nextpage name="p2" />
<div class="page-6 page-dedicatoria">
{{order.dedicatoria}} <br /> {{order.de}}
</div>
<p> </p>
</body>
</html>
Anyone knows why is using Helvetica? Or there is any way to embed Helvetica? I'm trying with "#font-face" but It's not working.
Helvetica is one of the standard fonts that every PDF renderer has to have available. Therefore it doesn't have to be embedded.
A possible solution would be to use another sans-serif font instead of Helvetica. On windows e.g. Arial. On OSX e.g. Helvetica Neue or Avenir. They look a lot like Helvetica, but are not standard PDF fonts.
In your stylesheet, specify a new font for all elements;
* {
font-family: Avenir;
}
I'm using the html2pdf python library, and would like to define a header and a footer to apply to each page (including fun things, like a page count for the footer). What is the most expedient method I can use to specify headers/footers with html2pdf?
See if this is what needs friend. The header and footer is fixed and informs the count of pages.
<?php
/**
* HTML2PDF Librairy - example
*
* HTML => PDF convertor
* distributed under the LGPL License
*
* #author Laurent MINGUET <webmaster#html2pdf.fr>
*
* isset($_GET['vuehtml']) is not mandatory
* it allow to display the result in the HTML format
*/
ob_start();
// HTML template begin (no output)
?>
<style type="text/css">
<!--
table.page_header {width: 100%; border: none; background-color: #DDDDFF; border-bottom: solid 1mm #AAAADD; padding: 2mm }
table.page_footer {width: 100%; border: none; background-color: #DDDDFF; border-top: solid 1mm #AAAADD; padding: 2mm}
div.niveau
{
padding-left: 5mm;
}
-->
</style>
<page backtop="14mm" backbottom="14mm" backleft="10mm" backright="10mm" style="font-size: 12pt">
<page_header>
<table class="page_header">
<tr>
<td style="width: 100%; text-align: left;">
Exemple d'utilisation des bookmarks
</td>
</tr>
</table>
</page_header>
<page_footer>
<table class="page_footer">
<tr>
<td style="width: 100%; text-align: right">
page [[page_cu]]/[[page_nb]]
</td>
</tr>
</table>
</page_footer>
</page>
<?php
// HTML end
// Getting the html which was not displayed into $content var
$content = ob_get_clean();
require_once(dirname(__FILE__).'/../html2pdf.class.php');
try
{
$html2pdf = new HTML2PDF('P', 'A4', 'fr', true, 'UTF-8', 0);
$html2pdf->writeHTML($content, isset($_GET['vuehtml']));
$html2pdf->createIndex('Sommaire', 25, 12, false, true, 1);
$html2pdf->Output('bookmark.pdf');
}
catch(HTML2PDF_exception $e) {
echo $e;
exit;
}
Easy Blueberry! You can use pages and frames to define headers and footers by placing them in your HTML doc's style tag.
<html>
<head>
<style>
/* Page margins are defined using CSS */
#page {
margin: 1cm;
margin-top:2.5cm;
margin-bottom: 2.5cm;
/* Header frame starts within margin-top of #page */
#frame header {
-pdf-frame-content: headerContent; /* headerContent is the #id of the element */
top: 1cm;
margin-left: 1cm;
margin-right:1cm;
height:1cm;
}
/* Footer frame starts outside margin-bottom of #page */
#frame footer {
-pdf-frame-content: footerContent;
bottom: 2cm;
margin-left: 1cm;
margin-right: 1cm;
height: 1cm;
}
}
</style>
</head>
<body>
<div id="headerContent">I'm a header!</div>
<p>I could be some content</p>
<div id="footerContent">I'm a footer! <pdf:pagenumber></div>
</body>
</html>
pdf:pagenumber is a tag used to display page count. There are many more tags included. Just refer to the official documentation!
Source: HTML2PDF Github Documentation