Tag: HTML

Generate PDF using python and HTML

Dependencies:

sudo pip3 install pdfkit
sudo apt-get install wkhtmltopdf

Pdfkit and wkhtmltopdf are the packages that you will be required before getting started.

PDF can be generated in 3 ways. One is using a website url, second one is using a html string and the last one is using a html file(optional css file can also be specified in all 3 ways).

In this article we will discuss the third way which is more advanced one and will be most useful for most of our requirements. Below is the program I am going to use to generate the PDF.

import pdfkit
import sys

inputfile = sys.argv[1]
outfile = args.argv[2]

options = {
      "enable-local-file-access": True,
      "enable /var/www/html/": True,
    'page-size': 'Letter',
    'margin-top': '0.75in',
    'margin-right': '0.75in',
    'margin-bottom': '0.75in',
    'margin-left': '0.75in',
    'encoding': "UTF-8",
    'custom-header': [
        ('Accept-Encoding', 'gzip')
    ],
    'cookie': [
        ('cookie-empty-value', '""'),
        ('cookie-name1', 'cookie-value1'),
        ('cookie-name2', 'cookie-value2'),
    ],
    'no-outline': None
}
# Single CSS file
css = 'bootstrap.css'

#pdfkit.from_url('http://google.com', 'out1.pdf')
pdfkit.from_file(inputfile, outfile, options=options, css=css)
#pdfkit.from_string('Hello!', 'out3.pdf')

In the code we can notice at the bottom that we can use a URL, local html file or a plain html string. Also a bootstrap.css file is being used for our styles. Common options that can be used to configure the PDF can also be seen in the above code. For full list of options that can be used read the documentaion here.

Now this code takes two arguments first one is input html file and the other being name of the output pdf that you want to generate into.

More documentaion regarding WKHTMLTOPDF can be read here.

Python program for Generating pdf using html content

HTML Forms

HTML forms are used to pass data to a server either using get/post method.

A form can contain input elements like text fields, check-boxes, radio-buttons, submit buttons and more. A form can also contain select lists, text area and label elements.

The <form> tag is used to create an HTML form:

<form>
.
input elements
.
</form>

HTML Forms – The Input Element

The most important form element is the input element.

The input element is used to select user information.

An input element can vary in many ways, depending on the type attribute. An input element can be of type text field, checkbox, password, radio button, submit button, and more.

The most used input types are described below.

Text Fields

Text Fields a one-line input field that a user can enter text into

<input type="text" />

<form>
First name: <input type="text" name="firstname"><br>
Last name: <input type="text" name="lastname">
</form>

The above HTML code looks like below in a browser:

Form fields with input type text

Password Field

<form>
Password: <input type="password" name="pwd" />
</form>

The above code will look like below in the browser

Password field in form in browser

Note: The characters in a password field are masked (i.e, shown as asterisks or black dots). 

Radio Buttons

Radio buttons let a user select only one one of a limited number of choices.

<form>
<input type="radio" name="sex" value="male" /> Male<br />
<input type="radio" name="sex" value="female" /> Female
</form>

Radio buttons in browser

Checkboxes

Checkboxes let a user select one or more options of a limited number of choices. For example selecting all the vehicles I own while filling a form.

<form>
<input type="checkbox" name="vehicle" value="Bike" /> I have a bike<br />
<input type="checkbox" name="vehicle" value="Car" /> I have a car 
</form>

Checkbox in browser

Submit Button

A submit button is used to send form data to a server. The data is sent to the page specified in the form’s action attribute. The api/server defined in the action attribute usually does something with the received input and does generate appropriate response and pass it back to the client/user.

<form name="input" action="html_form_action.php" method="get">
Username: <input type="text" name="user" />
<input type="submit" value="Submit" />
</form>

Form submit button in browser

If you type some characters in the text field above and click the “Submit” button, the browser will send your input to a page called “html_form_action.php”. In that page(php) you can access all the data received and process it accordingly.

All html tags explained with a short definition

TagDescription
<!–…–>Defines a comment
<!DOCTYPE> Defines the document type
<a>Defines an anchor
<abbr>Defines an abbreviation
<acronym>Defines an acronym
<address>Defines contact information for the author/owner of a document
<applet>Deprecated. Defines an embedded applet
<area />Defines an area inside an image-map
<b>Defines bold text
<base />Defines a default address or a default target for all links on a page
<basefont />Deprecated. Defines a default font, color, or size for the text in a page
<bdo>Defines the text direction
<big>Defines big text
<blockquote>Defines a long quotation
<body>Defines the document’s body
<br />Defines a single line break
<button>Defines a push button
<caption>Defines a table caption
<center>Deprecated. Defines centered text
<cite>Defines a citation
<code>Defines computer code text
<col />Defines attribute values for one or more columns in a table 
<colgroup>Defines a group of columns in a table for formatting
<dd>Defines a description of a term in a definition list
<del>Defines deleted text
<dfn>Defines a definition term
<dir>Deprecated. Defines a directory list
<div>Defines a section in a document
<dl>Defines a definition list
<dt>Defines a term (an item) in a definition list
<em>Defines emphasized text 
<fieldset>Defines a border around elements in a form
<font>Deprecated. Defines font, color, and size for text
<form>Defines an HTML form for user input
<frame />Defines a window (a frame) in a frameset
<frameset>Defines a set of frames
<h1> to <h6>Defines HTML headings
<head>Defines information about the document
<hr />Defines a horizontal line
<html>Defines an HTML document
<i>Defines italic text
<iframe>Defines an inline frame
<img />Defines an image
<input />Defines an input control
<ins>Defines inserted text
<isindex>Deprecated. Defines a searchable index related to a document
<kbd>Defines keyboard text
<label>Defines a label for an input element
<legend>Defines a caption for a fieldset element
<li>Defines a list item
<link />Defines the relationship between a document and an external resource
<map>Defines an image-map 
<menu>Deprecated. Defines a menu list
<meta />Defines metadata about an HTML document
<noframes>Defines an alternate content for users that do not support frames
<noscript>Defines an alternate content for users that do not support client-side scripts
<object>Defines an embedded object
<ol>Defines an ordered list
<optgroup>Defines a group of related options in a select list
<option>Defines an option in a select list
<p>Defines a paragraph
<param />Defines a parameter for an object
<pre>Defines preformatted text
<q>Defines a short quotation
<s>Deprecated. Defines strikethrough text
<samp>Defines sample computer code
<script>Defines a client-side script
<select>Defines a select list (drop-down list)
<small>Defines small text
<span>Defines a section in a document
<strike>Deprecated. Defines strikethrough text
<strong>Defines strong text
<style>Defines style information for a document
<sub>Defines subscripted text
<sup>Defines superscripted text
<table>Defines a table
<tbody>Groups the body content in a table
<td>Defines a cell in a table
<textarea>Defines a multi-line text input control
<tfoot>Groups the footer content in a table
<th>Defines a header cell in a table
<thead>Groups the header content in a table
<title>Defines the title of a document
<tr>Defines a row in a table
<tt>Defines teletype text
<u>Deprecated. Defines underlined text
<ul>Defines an unordered list
<var>Defines a variable part of a text
<xmp>Deprecated. Defines preformatted text
HTML tags

All the html tags format the text accordingly.

Its up to the developer to use appropriate tag according to the requirement.

Some of the major attributes are explained below that will go with almost every html tag element.

AttributeValueDescription
classclassnameSpecifies a classname for an element(refereed to using . selector)
ididSpecifies a unique id for an element(refereed using # selector )
stylestyle_definitionSpecifies an inline style for an element(inline CSS)
titletooltip_text Specifies extra information about an element (displayed as a tool tip on mouse hover)
Major HTML attributes

Linking a Python script to a web interface with file upload.

In this article I am going to explain how can we link a python script with a web interface. In case you need the GIT hub link for the entire project you can find it here.

Requirements:

  • PHP
  • Web Server(apache)
  • Javascript
  • A Python script that you want to link with the web interface.

The Python Script

#convert text to lowercase 

import sys
#open file using open file mode
fp1 = open(sys.argv[1]) # Open file on read mode -- input file
lines = fp1.read().split("\n") # Create a list containing all lines
fp1.close() # Close file

#write output to a file name it out.txt
fp2 = open("out.txt", "w")

#do something with the text and write it to the file
for line in lines:
	out_line = line.lower()
	fp2.write(out_line + "\n")


fp2.close()

This is our Python script that we want to use it from a Wen Interface where we give input text and the lower case text is shown in the web page itself. Remember I am here just taking a very small example this python script could be doing anything but the basic point is that it takes an input file with some text and writes the output to another file.

To make sure this works, run this python script independently and see if it works as expected.

python3 case_convert.py in.txt
  • Replace your python script with your code.
  • If you have any other script like in PERL, Shell script even then it works fine. You just need to change it in PHP script where it calls the system command.

This script takes a input file in.txt that contains some text and it will be converted to lower case when we execute the script and save it to a output file out.txt

Now lets build our Web page we will call it as index.html It will look like below.

<html>
	<head>
		<title>
			A Web Interface
		</title>

		<script src="js/jquery.js"></script>
		<script src="js/jquery-ui.js"></script>
		<script type="text/javascript" src="config.js"></script>
		<script type="text/javascript" src="js/FileSaver.js"></script>
		<script type="text/javascript" src="js/validation.js"></script>

		<link rel="stylesheet" type="text/css" href="bootstrap-3.3.5-dist/css/bootstrap.css" />
		<link rel="stylesheet" type="text/css" href="css/styles.css" />
		<link rel="stylesheet" type="text/css" href="css/responsive.css" />

		<script type="text/javascript" src="bootstrap-3.3.5-dist/js/bootstrap.js" ></script>
		<script type="text/javascript" src="js/convert.js" ></script>

		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
		 <meta charset='utf-8'>
	</head>
	<body>
		<div>

				<h4 align="center">Convert Upper case to LowerCase </h4>
			<!--common for file and text output-->
			<!--upload form-->
			<form class="form-inline" id="upload" method="post" enctype="multipart/form-data">

				<div class="form-group col-12 col-m-12">
					
					<label class="btn btn-primary" for="my-file-selector">

						<!--<input accept=".doc,.rtf,.docx,.pdf,text/plain" type="file" id="file" name="inputfile" multiple/>-->
						<input accept=".pdf,text/plain,.doc" type="file" id="file" name="inputfile" onchange="startRead(this)" multiple  multiple/>
					</label>

					<!--<button type="button" class="form-control btn btn-default dropdown-toggle" data-toggle="dropdown">
						Select Business type <span class="caret"></span>
					</button>-->
				<!--	<span id="mandatory">*</span> <select name="srclanguage"  id="srclanguage" class="form-control"><option value="" >Choose Type</option>
						<option disabled="true"></option>
				</select>-->

					<button id="submit" type="button" class="btn btn-default navbar-btn" onclick="submittext();">
						Submit
					</button>
					<img style="margin-left:2%;height:4%;position:relative;" id="loading" src="images/processing.gif"></img>
					<br>
			<textarea id="input"></textarea> 
			<textarea id="result"></textarea> 
					<button id="edit" type="button" class="btn btn-default navbar-btn" onclick="edittext();">
						Edit
					</button>
					<br>
					<button id="sample1" type="button" class="btn btn-default navbar-btn sample" onclick="sample(this.id);">
						Sample1
					</button>
					<button id="sample2" type="button" class="btn btn-default navbar-btn sample" onclick="sample(this.id);">
						Sample2
					</button>
					<button id="sample3" type="button" class="btn btn-default navbar-btn sample" onclick="sample(this.id)">
						Sample3
					</button>
					<button id="clear" type="button" class="btn btn-default navbar-btn" onclick="empty();">
						clear
					</button>
					<select style="background-color:#7ba733;color:#fff;" name="savetype"  id="savetype" class="form-control"><option value="" >Export to</option>
						<option disabled="true"></option>
						<option value="txt">.txt </option>
						<option value="csv">.csv </option>
						<option value="doc">.doc</option>
						<option value="rtf">.rtf</option>
						<option value="pdf">.pdf</option>
					</select>

					<button id="download" type="button" disabled class="btn btn-default navbar-btn" onclick="saveasfile();">
						Download
					</button>

				</div> <!-- end of form group div -->

			</form>


			<div class="progressbar">
				<div class="bar">
				</div>

			</div> <!-- end of progressbar div-->

			<!--<div contenteditable="true" id="result"></div>--> <!-- end of result div-->
			<!--			<textarea onkeypress="txtAreaId(this.id);" id="result-text"></textarea> -->

		</div>	<!-- end of container div -->
	</body>
</html>

Looks like a lot but it simply does hold two textareas, button for submitting input text, downloading the output text and linked Javascript and CSS files.

The main Javascript file convert.js which is in js folder will call a PHP script that will execute our python program. I will just list the main function here that is activated when we click submit after inputting some text.

//called when submit button button is clicked
function submittext(){
	$("#savetype").hide();
	$("#download").hide();
	//$("#result").hide();

	//retrieve values from fields
	var srctext = $("#input").val();
	//alert(fromto+" "+srctext);
	
	
	if(typeof srctext =="undefined" || srctext =="") {
		alert("Provide some text...");
		return false;
	}


	$("#loading").show();
	$("#result").empty();
	//Ajax call to upload and submit for conversion
	$.ajax({
		type: 'POST',
		url: "scripts/convert.php",
		//data: "&from=" + from + "&to=" + to + "&text=" + srctext,
		data: "&text=" + srctext,
		header:"application/x-www-form-urlencoded",
		async:false,
		success: function (data) {
			$("#loading").hide();
			//alert(data);
			var tgttext = data;
			$("#result").val(tgttext);
			$('#download').prop('disabled', false);
			$('#language').prop('disabled', false);
			$("#savetype").show();
			$("#download").show();
			$("#edit").show();
		
		},
		error:function  (jqXHR, exception) {
			$("#loading").hide();
			var msg = '';
			if (jqXHR.status === 0) {
				msg = 'Not connect.\n Verify Network.';
			} else if (jqXHR.status == 404) {
				msg = 'Requested page not found. [404]';
			} else if (jqXHR.status == 500) {
				msg = 'Internal Server Error [500].';
			} else if (exception === 'parsererror') {
				msg = 'Requested JSON parse failed.';
			} else if (exception === 'timeout') {
				msg = 'Time out error.';
			} else if (exception === 'abort') {
				msg = 'Ajax request aborted.';
			} else {
				msg = 'Uncaught Error.\n' + jqXHR.responseText;
			}
			alert(msg+" Please try afer sometime");
		}
	});
	return false;
}

So we can see that we are using AJAX which explains why we need jQuery. In the AJax look at the URL it is calling a PHP script convert.php located in scripts directory.

convert.php will look like below. I recommend PHP 7 although it works in lower versions too.

<?php
$text = $_POST["text"];

$fp = fopen("in.txt","w");
fwrite($fp,$text);
fclose($fp);

#call your python script here and make sure your python script is also at same place as this script
$status = system("python3 case_convert.py in.txt");

$fp_out = fopen("out.txt","r");
if ($fp_out) {
    while (($line = fgets($fp_out)) !== false) {
        // process the line read.
        echo "$line";
    }

    fclose($fp_out);
} else {
    // error opening the file.
}

?>

After doing all these. You need to give proper permission the scripts directory or just the two files in.txt and out.txt. Below is the command to do the same.

chown www-data:www-data scripts 
chown www-data:www-data in.txt out.txt

After doing this load your web page in the browser. For example I named the directory as basic-web-interface, so in my browser I open it as http://localhost/basic-web-interface/.

If you have PHP/ APACHE and all other javascript and Bootstrap files installed it should load your web page without any hiccups.

Then provide some input text and see that it gets convert to lowercase and the output text is displayed in the other textarea.

Debugging
  • Check apache error..log file for errors. For ubuntu it is /var/log/apache2/error.log
  • Open Network console(F12) from Browser Developer options and view the API request that is being called. Its request, response, parameters etc.
  • For this Open Developer options, click on network tab and then click submit and view the request/reponse.