Save html page as PDF | HTML2PDF - html

I need to save a table in a HTML page in PDF Format.
As you can I have 30 columns in this table.
see image
I made a javascript function (using HTML2PDF library), that the button "Genera PDF" will download the table in PDF Format.
There is the javascript function:
function generatePDF(){
element = document.getElementById("table-bordered");
var opt = {
filename: 'myreport.pdf',
image: { type: 'jpeg', quality: 0.98 },
jsPDF: { unit: 'in', format: 'A4', orientation: 'landscape' }
};
htmltopdf().from(element).set(opt).save();
}
The problem is that the PDF comes out with a bad layout (is not center on the page and the columns goes only to 27.)
PDF file
How I have to modify my code as it work well?
Otherwise, there is another possibility other html2pdf for doing this work?
Thank you

You can use the js pdf. My requirement is almost done with that. I hope it will work for you.
$(document).ready(function () {
var form = $('.form'),
cache_width = form.width(),
a4 = [595.28, 841.89]; // for a4 size paper width and height
$('#create_pdf').on('click', function () {
$('body').scrollTop(0);
createPDF();
});
function createPDF() {
getCanvas().then(function (canvas) {
var
img = canvas.toDataURL("image/png"),
doc = new jsPDF({
unit: 'px',
format: 'a4'
});
doc.addImage(img, 'JPEG', 20, 20);
doc.save('Invoice');
form.width(cache_width);
});
}
function getCanvas() {
form.width((a4[0] * 1.33333) - 80).css('max-width', 'none');
return html2canvas(form, {
imageTimeout: 2000,
removeContainer: true
});
}
});
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
background-color: #111;
color: white;
}
tr:nth-child(odd) {
background-color: #dddddd;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PDF</title>
</head>
<body>
<h1>How To Convert HTML To PDF Using JavaScript</h1>
<form class="form">
<table>
<tbody>
<tr>
<th>Company Name</th>
<th>Employee Name</th>
<th>Country</th>
</tr>
<tr>
<td>Dell</td>
<td>Maria</td>
<td>Germany</td>
</tr>
<tr>
<td>Asus</td>
<td>Francisco</td>
<td>Mexico</td>
</tr>
<tr>
<td>Apple</td>
<td>Roland</td>
<td>Austria</td>
</tr>
<tr>
<td>HP</td>
<td>Helen</td>
<td>UK</td>
</tr>
<tr>
<td>Lenovo</td>
<td>Yoshi</td>
<td>Canada</td>
</tr>
</tbody>
</table><br>
<input type="button" id="create_pdf" value="Generate PDF">
</form>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>
</html>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.4/jspdf.min.js"></script>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 50%;
margin: 0px auto;
}
#htmlContent{
text-align: center;
}
td, th, button {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
button {
border: 1px solid black;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
<div id="htmlContent">
<h2 style="color: #0094ff">Hello</h2>
<h3>About this Code:</h3>
<p>Demo of how to convert and Download HTML page to PDF file with CSS, using JavaScript and jQuery.</p>
<table>
<tbody>
<tr>
<th>Person</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>John</td>
<td>+2345678910</td>
<td>Germany</td>
</tr>
<tr>
<td>Jacob</td>
<td>+1234567890</td>
<td>Mexico</td>
</tr>
<tr>
<td>Eleven</td>
<td>+91234567802</td>
<td>Austria</td>
</tr>
</tbody>
</table>
</div>
<div id="editor"></div>
<center>
<p>
<button id="generatePDF">generate PDF</button>
</p>
Ref:phpcoder.tech
</center>
The Js Code
var doc = new jsPDF();
var specialElementHandlers = {
'#editor': function (element, renderer) {
return true;
}
};
//margins.left, // x coord margins.top, { // y coord
$('#generatePDF').click(function () {
doc.fromHTML($('#htmlContent').html(), 15, 15, {
'width': 700,
'elementHandlers': specialElementHandlers
});
doc.save('sample_file.pdf');
});

Related

Cannot remove padding in table

I am trying to remove the padding from the cells inside my table. I have set it to not have padding in the relevant CSS selectors but not a success.
As you can see, there is padding on all of these cells.
I would like there to not be. I have tried various different padding settings and changing the vertical alignment makes no difference other than to move the text, the padding just goes from all at the bottom to spread between bottom and top.
Below is the code:
'use strict'
let table = document.getElementById("mainTable")
let rows = table.querySelectorAll("tbody tr")
let columns = table.querySelectorAll("#weeks th")
for (let row of rows) {
for (let o = 0; o<columns.length-1; o++) {
let cell = document.createElement("td")
cell.innerHTML='&nbsp'
cell.addEventListener("click", function() {
if (cell.getElementsByTagName("input")[0]) { return } //If cell currently has an input box
//
let oldValue = ""
if (cell.innerHTML !== " ") { //if cell has a saved value
oldValue = cell.innerHTML
}
cell.innerHTML = '<input type="text" class="cellInputs">'
//update input box with old value and focus it
cell.getElementsByTagName("input")[0].focus()
cell.getElementsByTagName("input")[0].value = oldValue
cell.getElementsByTagName("input")[0].addEventListener("keypress", function(e) {
if (e.keyCode === 13) {
cell.innerHTML=cell.getElementsByTagName("input")[0].value
e.preventDefault()
return true
}
})
cell.getElementsByTagName("input")[0].addEventListener("input", function(e) {
console.log(e)
let cellValue = cell.getElementsByTagName("input")[0].value
if (e.data === "." && (cellValue.split('.').length-1 > 1 || cellValue === ".")) {
console.log("stop")
cell.getElementsByTagName("input")[0].value = (cellValue).substring(0, cellValue.length - e.data.length)
}
if (isNaN(e.data) && e.data !==".") {
console.log("Stop")
cell.getElementsByTagName("input")[0].value = (cellValue).substring(0, cellValue.length - e.data.length)
}
//store value inputted into the actual cell
})
cell.getElementsByTagName("input")[0].addEventListener("paste", function(e) {
// clipboardData = e.clipboardData || window.clipboardData;
// pastedData = clipboardData.getData('Text');
let cellValue = cell.getElementsByTagName("input")[0].value
if (cellValue !== "") {
e.preventDefault()
return false
}
if (e.clipboardData.getData('text') === "." && (cellValue.split('.').length-1 > 1 || cellValue === ".")) {
e.preventDefault()
return false
}
if (isNaN(e.clipboardData.getData('text')) && e.clipboardData.getData('text') !==".") {
e.preventDefault()
return false
}
//store value inputted into the actual cell
})
cell.getElementsByTagName("input")[0].addEventListener("focusout", function() {
console.log(document.activeElement)
cell.innerHTML=cell.getElementsByTagName("input")[0].value
})
})
row.appendChild(cell)
}
}
*{
padding: 0;
margin: 0;
font-family: "Trebuchet MS", Times, serif;
box-sizing:border-box;
}
html{
background-color: #35454E;
overflow: hidden;
}
html *{
font-family: "Work Sans", Arial, sans-serif !important;
color: white !important;
}
table{
border-collapse: collapse;
border-spacing: 0px;
color:#35454E;
height:100%;
width:100%;
}
table, th{
border: 2px solid white;
padding:0;
}
th{
vertical-align:top;
font-size: 2.5vw;
}
td{
vertical-align:top;
box-sizing:border-box;
position: relative;
border: 2px solid white;
padding:0;
text-align: center;
font-size: 2.5vw;
padding:0;
}
.cellInputs{
position: absolute;
width:100%;
height:100%;
display: block;
top:0;
left:0;
border:none;
text-align: center;
background-color: #35454E;
word-wrap: break-word;
font-size: 2.5vw;
}
<html>
<head>
<link rel="stylesheet" type="text/css" href="MMS.css">
<title>Money Management</title>
</head>
<body>
<table id="mainTable">
<thead>
<tr>
<th>2019</th>
<th colspan="5">January</th>
</tr>
<tr id="weeks">
<th>&nbsp</th>
<th>31/12/2018</th>
<th>07/01/2019</th>
<th>14/01/2019</th>
<th>21/01/2019</th>
<th>28/01/2019</th>
</tr>
</thead>
<tbody>
<tr>
<th>Balance</th>
</tr>
<tr>
<th>Pay</th>
</tr>
<tr>
<th>&nbsp</th>
</tr>
<tr>
<th>Rent</th>
</tr>
<tr>
<th>Food</th>
</tr>
<tr>
<th>&nbsp</th>
</tr>
<tr>
<th>Total</th>
</tr>
</tbody>
</table>
</body>
<script src="MMS.js"></script>
</html>
Remove height:100% from table .

Removing space between table doesn't seem to be working

I've got a grid that I want to be as absolute as possible; preferably with 1px between each td. My issue though is that seemingly nothing I do reduces the space between the td or evens the larger space between tr.
When you click Update Preview in my code the desired result should be even spacing between the td; I want the td to have the same size as the canvases. Here's a JSFiddle, and my code:
Fixed Snippet:
var canvas = [];
canvas.push(new fabric.Canvas('c0'));
for (i = 1; i <= 7; i++) {
canvas.push(new fabric.StaticCanvas('sc' + i));
}
var rect = new fabric.Rect({
fill: '#F5F5F5',
width: 187.5,
height: 318.75
});
canvas[0].add(rect);
$('#update').click(function() {
var json = JSON.stringify(canvas[0]);
for (i = 1; i <= 7; i++) {
canvas[i].loadFromJSON(json);
}
});
$('#save').click(function() {
html2canvas($('#imagesave'), {
onrendered: function(canvas) {
var a = document.createElement('a');
// toDataURL defaults to png, so we need to request a jpeg, then convert for file download.
a.href = canvas.toDataURL("image/jpeg").replace("image/jpeg", "image/octet-stream");
a.download = 'myfile.jpg';
a.click();
}
});
});
body {
margin: 0px;
padding: 0px;
}
canvas {
border: 0px solid #f00;
margin: 0px;
display: block;
}
td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
vertical-align: baseline;
}
#imagesave {
background-color: white;
height: 637.5px;
width: 825px;
padding-left: 75px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<button id="update">Update Preview</button>
<button id="save">Save</button>
<div id="imagesave">
<table>
<tr>
<td>
<canvas id="c0" width="187.5" height="318.75"></canvas>
</td>
<td>
<canvas id="sc1" width="187.5" height="318.75"></canvas>
</td>
<td>
<canvas id="sc2" width="187.5" height="318.75"></canvas>
</td>
<td>
<canvas id="sc3" width="187.5" height="318.75"></canvas>
</td>
</tr>
<tr>
<td>
<canvas id="sc4" width="187.5" height="318.75"></canvas>
</td>
<td>
<canvas id="sc5" width="187.5" height="318.75"></canvas>
</td>
<td>
<canvas id="sc6" width="187.5" height="318.75"></canvas>
</td>
<td>
<canvas id="sc7" width="187.5" height="318.75"></canvas>
</td>
</tr>
</table>
</div>
Try adding:
canvas {
display: block;
}

How to center pagination buttons after table? text-align not working

This seems really simple but I am struggling with CSS.
Basically I have a table and after it I use a pagination system to navigate through the table content. The real table has more information, I just used an example to make it look simpler.
I am having a problem trying to center the buttons for the pagination after the table. The text-align property does not seem to be working and I am not sure why.
How can I center the buttons in the center considering the 100% width.
Thanks.
$(document).ready(function() {
$('#table').after('<div id="nav" class="pagination"></div>');
var rowsShown = 2;
var rowsTotal = $('#table tbody tr').length;
var numPages = rowsTotal / rowsShown;
for (i = 0; i < numPages; i++) {
var pageNum = i + 1;
$('#nav').append('' + pageNum + ' ');
}
$('#table tbody tr').hide();
$('#table tbody tr').slice(0, rowsShown).show();
$('#nav a:first').addClass('active');
$('#nav a').bind('click', function() {
$('#nav a').removeClass('active');
$(this).addClass('active');
var currPage = $(this).attr('rel');
var startItem = currPage * rowsShown;
var endItem = startItem + rowsShown;
$('#table tbody tr').css('opacity', '0.0').hide().slice(startItem, endItem).
css('display', 'table-row').animate({
opacity: 1
}, 300);
});
});
.table {
width: 100%;
}
.pagination {
display: inline-block;
width: 100%;
text-align: center;
}
.pagination a {
color: black;
float: left;
padding: 8px 16px;
text-decoration: none;
transition: background-color .3s;
}
.pagination a.active {
background-color: #4CAF50;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table id="table" class="table">
<thead>
<tr>
<th>Name</th>
<th>Item</th>
</tr>
</thead>
<tbody id="tbody">
<tr>
<td>Sarah</td>
<td>3</td>
</tr>
<tr>
<td>Tom</td>
<td>3</td>
</tr>
<tr>
<td>Kate</td>
<td>1</td>
</tr>
<tr>
<td>Michael</td>
<td>1</td>
</tr>
</tbody>
</table>
You can do this.
$(document).ready(function() {
$('#table').after('<div id="nav" class="pagination"></div>');
var rowsShown = 2;
var rowsTotal = $('#table tbody tr').length;
var numPages = rowsTotal / rowsShown;
for (i = 0; i < numPages; i++) {
var pageNum = i + 1;
$('#nav').append('' + pageNum + ' ');
}
$('#table tbody tr').hide();
$('#table tbody tr').slice(0, rowsShown).show();
$('#nav a:first').addClass('active');
$('#nav a').bind('click', function() {
$('#nav a').removeClass('active');
$(this).addClass('active');
var currPage = $(this).attr('rel');
var startItem = currPage * rowsShown;
var endItem = startItem + rowsShown;
$('#table tbody tr').css('opacity', '0.0').hide().slice(startItem, endItem).
css('display', 'table-row').animate({
opacity: 1
}, 300);
});
});
.table {
width: 100%;
}
.pagination {
display: inline-block;
width: 100%;
text-align: center;
display:flex;
justify-content:center;
}
.pagination a {
color: black;
float: left;
padding: 8px 16px;
text-decoration: none;
transition: background-color .3s;
}
.pagination a.active {
background-color: #4CAF50;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table id="table" class="table">
<thead>
<tr>
<th>Name</th>
<th>Item</th>
</tr>
</thead>
<tbody id="tbody">
<tr>
<td>Sarah</td>
<td>3</td>
</tr>
<tr>
<td>Tom</td>
<td>3</td>
</tr>
<tr>
<td>Kate</td>
<td>1</td>
</tr>
<tr>
<td>Michael</td>
<td>1</td>
</tr>
</tbody>
</table>

Filter table with multiple columns

Just trying to filter a table but also have it filter the number with and without dashes (working) but also search the name and id as well. Its only searching the one column since the index is [0].
How would I have it search all 3 columns? So if I search number or id or name it would filter. Here is the working code I have so far to search number.
<!DOCTYPE html>
<html>
<head>
<style>
* {
box-sizing: border-box;
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 18px;
}
#myTable th, #myTable td {
text-align: left;
padding: 12px;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#myTable tr.header, #myTable tr:hover {
background-color: #f1f1f1;
}
</style>
</head>
<body>
<h2>Number search</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Number</th>
<th style="width:60%;">Name</th>
<th style="width:60%;">ID</th>
</tr>
<tr>
<td>905-373-3333</td>
<td>Mike</td>
<td>4563</td>
</tr>
<tr>
<td>905-333-3333</td>
<td>adam</td>
<td>8963</td>
</tr>
<tr>
<td>416-373-3432</td>
<td>Jim</td>
<td>9363</td>
</tr>
</table>
<script>
function myFunction() {
var input, filter, table, tr, td, i, cleanedFilter;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
cleanedFilter = filter.replace("-","");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
cellContent = td.innerHTML.toUpperCase().replace(/-/g,"");
if (cellContent.indexOf(cleanedFilter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>
</body>
</html>
If you want to use a filter for every td available in your rows, you can use the following:
(function(document) {
'use strict';
var LightTableFilter = (function(Arr) {
var _input;
function _onInputEvent(e) {
_input = e.target;
var tables = document.getElementsByClassName(_input.getAttribute('data-table'));
Arr.forEach.call(tables, function(table) {
Arr.forEach.call(table.tBodies, function(tbody) {
Arr.forEach.call(tbody.rows, _filter);
});
});
}
function _filter(row) {
var text = row.textContent.toLowerCase(), val = _input.value.toLowerCase();
row.style.display = text.indexOf(val) === -1 ? 'none' : 'table-row';
}
return {
init: function() {
var inputs = document.getElementsByClassName('light-table-filter');
Arr.forEach.call(inputs, function(input) {
input.oninput = _onInputEvent;
});
}
};
})(Array.prototype);
document.addEventListener('readystatechange', function() {
if (document.readyState === 'complete') {
LightTableFilter.init();
}
});
})(document);
<section class="container">
<input type="search" class="light-table-filter" data-table="order-table" placeholder="Filter">
<table class="order-table table">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Number 2</th>
<th>Number 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Column One</td>
<td>Two</td>
<td>352353</td>
<td>1</td>
</tr>
<tr>
<td>Column Two</td>
<td>Two</td>
<td>4646</td>
<td>2</td>
</tr>
</tbody>
</table>
</section>

How can i google map v3 coordinates insert to mysql (lat,lng) with AUTOCOMPLETE

This code not work.
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: Map Simple</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&libraries=places"></script>
<script type="text/javascript">
var placeSearch,autocomplete;
var component_form = {
'street_number': 'short_name',
'route': 'long_name',
'locality': 'long_name',
'country': 'long_name',
'postal_code': 'short_name',
//'location':'lat',
//'location':'lng'
};
function initialize() {
autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'), { types: [ 'geocode' ] });
google.maps.event.addListener(autocomplete, 'place_changed', function() {
fillInAddress();
});
}
function fillInAddress() {
var place = autocomplete.getPlace();
//var lat = place.geometry.location.lat();
//var lng = place.geometry.location.lng();
for (var component in component_form) {
document.getElementById(component).value = "";
document.getElementById(component).disabled = false;
}
for (var j = 0; j < place.address_components.length; j++) {
var att = place.address_components[j].types[0];
if (component_form[att]) {
var val = place.address_components[j][component_form[att]];
document.getElementById(att).value = val;
}
}
}
function geolocate() {
var place = autocomplete.getPlace();
//var lat = place.geometry.location.lat();
//var lng = place.geometry.location.lng();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var geolocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
autocomplete.setBounds(new google.maps.LatLngBounds(geolocation, geolocation));
});
}
}
</script>
<style>
body {
font-family: sans-serif;
margin: 0px;
padding: 0px;
}
#locationField, #controls {
position: relative;
width: 480px;
}
#autocomplete {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
}
.label {
text-align: right;
font-weight: bold;
width: 100px;
color: #303030;
}
#address {
border: 1px solid #000090;
background-color: #f0f0ff;
width: 480px;
}
#address td {
font-size: 10pt;
}
.field {
width: 100%;
}
.slimField {
width: 80px;
}
.wideField {
width: 200px;
}
#locationField {
height: 20px;
margin-bottom: 2px;
}
</style>
</head>
<body onload="initialize()">
<div id="locationField">
<input id="autocomplete" placeholder="Adresinizi Giriniz" onFocus="geolocate()" type="text"></input>
</div>
<table id="address">
<tr>
<td class="label">Sokak Adresi</td>
<td class="slimField"><input class="field" id="street_number" disabled="true"></input></td>
<td class="wideField" colspan="2"><input class="field" id="route" disabled="true"></input></td>
</tr>
<tr>
<td class="label"></td>
<td class="wideField" colspan="3"><input class="field" id="locality" disabled="true"></input></td>
</tr>
<tr>
<td class="label">Posta Kodu</td>
<td class="wideField"><input class="field" id="postal_code" disabled="true"></input></td>
</tr>
<tr>
<td class="label">Ülke</td>
<td class="wideField" colspan="3"><input class="field" id="country" disabled="true"></input></td>
</tr>
<tr>
<td class="label">Lat</td>
<td class="wideField" colspan="3"><input class="field" id="location" disabled="true"></input></td>
</tr>
<tr>
<td class="label">Lng</td>
<td class="wideField" colspan="3"><input class="field" id="location" disabled="true"></input></td>
</tr>
</table>
</body>
</html>
/*
Sample Reg: mysql_query("insert into gmap value (Null,$_POST[lat],$_POST[lng])"); ...etc
*/
Original link:
Gmaps v3 autocomplete form (Not showing lat lng)
Help please...