I have written some HTML-CSS in a file, It works perfectly in the browser but when I change the extendion to vm ( for apache velocity) . some of the css doesn't work . why is velocity not able to understand the css.
CODE:
<html>
<head>
<title>Letter</title>
<style>
.row {
width: 100%;
display:flex;
height:80px;
}
.column1 {
width:33%;
float: left;
}
.column2 {
width:33%;
float: center;
}
.column3 {
width:33%;
float: right;
}
body {
padding: 20px;
font-size: 12px;
font-family: Arial,Arial Unicode MS,Quivira,sans-serif,Wingdings;
}
#rcorners2 {
border-radius: 25px;
align-items:center;
border: 1px solid grey;
padding: 20px;
width: 1000px;
height: 50px;
display:flex;
}
.vl {
border-left: 1px solid grey;
height: 50px;
}
.gap{width:200px;background:none;height:200px;display:inline-block;}
</style>
</head>
<body>
<div class="row">
<div class="column1">
<img src="https://www.iconfinder.com/data/icons/pictype-free-vector-icons/16/home-512.png" height="50px" width="250" />
</div>
<div class="column2">
<h1 style="text-align: center;"> Letter Head</h1>
</div>
<div class="column3">
<h2 style="color:#AE275F;text-align: right;">SAMPLE</h2>
</div>
</div>
<div>
<div id="rcorners2" > </div>
<div>
<p>Date </p>
<p>MAY 28,2020</p>
</div>
<div class="gap">
</div>
<div class="vl"></div>
</div>
</body>
</html>
The problem was not with my velocity template. I was using Itext5 to convert HTML to PDF and as Itext5 does not support HTML5 , some of the features weren't working.
I am using openHtmlToPdf library for converting HTML to PDF and the css works perfectly now.
Related
I am generating PDF from HTML. I have table in HTML which will spans to multiple pages, When table spans multiple pages I need to display last row border of each page. I don't have row borders for table(which is expected). When table not ended in single page, I should display border of last row. Below is my code samples.
Java Code:
String html = ""
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(outputStream);
HTML:
<html>
<head>
<style>
#page{
#bottom-left {
content: element(footer);
vertical-align: top;
padding-top: 10px;
}
#top-right {
content: element(header);
vertical-align: bottom;
padding-bottom: 10px;
}
size: A4 portrait;
margin-top:5.5cm;
margin-left:3cm;
margin-right:2cm;
margin-bottom:3.3cm;
}
div.header {
display: block;
position: running(header);
border-bottom: 1px solid black;
}
div.footer {
margin-top: 0.5cm;
display: block;
position: running(footer);
border-top: 1px solid black;
}
div.content {
display: block;
width: 15.4cm;
text-align: justify;
}
#pagenumber:before {
content: counter(page);
}
#pagecount:before {
content: counter(pages);
}
</style>
</head>
<body>
<div class="header">
This is the header that will repeat on every page at top
</div>
<div class="footer" >
<p>This is the footer that will repeat on every page at bottom</p>
<p>Page <span id="pagenumber"></span> of <span id="pagecount"></span></p>
</div>
<div class="content">
<table
style="height: 250px; margin-top: 50px; border: 1px solid black"
cellpadding="0" cellspacing="0">
<tr class="heading" style="height: 1px;">
<td>Item</td>
<td>Quantity</td>
<td style="width:100px">Price</td>
<td style="text-align: right; padding-right: 20px;">Summa</td>
</tr>
<tr class="item" style="height: 24px; ">
<td>Row 1</td>
<td>19,75</td>
<td style="width:100px">10,00</td>
<td style="text-align: right; padding-right: 20px;">197,50</td>
</tr>
<tr class="item" style="height: 24px; ">
<td>Row 2</td>
<td>19,75</td>
<td style="width:100px">10,00</td>
<td style="text-align: right; padding-right: 20px;">197,50</td>
</tr>
<!-- 100 Rows -->
<tr class="item" style="height: 24px; ">
<td>Row N</td>
<td>19,75</td>
<td style="width:100px">10,00</td>
<td style="text-align: right; padding-right: 20px;">197,50</td>
</tr>
</table>
</div>
</body>
</html>
After HTML to PDF output as below
Just add the following CSS:
table {
-fs-table-paginate: paginate;
border-spacing: 0;
}
From the old Flying saucer user guide, the effect is to "modify the table layout algorithm to repeat table headers and footers on subsequent pages and improve the appearance of cells that break across pages (for example by closing and reopening borders)". As you don't have any header or footer in your table, it just adds the missing border.
The result looks like this:
I am trying to convert a HTML page to a PDF with the help of iText library. I do not have a lot experience and I am failing to get my image added in the PDF.
First I read a HTML template (that I use for the basis). The image is placed with the <img> tag as follows <img src="http://clipartmag.com/image/iron-man-face-drawing-6.png" class="avatar-image">. I retrieve a Document class from that template. I add the wanted content to the Document instance. Once that is done, I retrieve the html and use it to generate the PDF.
String resumeFilePath = String.format(RESUME_FILE_PATH, userProfileBean.getFirstname(), userProfileBean.getLastname());
Document resumeAsHtml = createHtmlDocument(userProfileBean);
HtmlConverter.convertToPdf(resumeAsHtml.html(), new FileOutputStream(resumeFilePath));
File newResume = new File(resumeFilePath);
In the testing phase, I even created the HTML page separately to see everything is in place - resumeAsHtml.html(). The web page had the image in the page. But when I call
HtmlConverter.convertToPdf(
resumeAsHtml.html(), new FileOutputStream(resumeFilePath));
the created PDF is missing the image. I also get 3 errors in the logs:
2019-09-29 10:06:22,678 ERROR c.i.s.c.p.s.CssParserStateController:495 - The rule #keyframes is unsupported. All selectors in this rule will be ignored.
2019-09-29 10:06:22,944 ERROR c.i.s.r.r.ResourceResolver:146 - Unable to retrieve image with given base URI (file:/Users/jklancic/dev/custom/resume/) and image source path (http://clipartmag.com/image/iron-man-face-drawing-6.png)
2019-09-29 10:06:22,947 ERROR c.i.h.a.i.DefaultHtmlProcessor:356 - Worker of type com.itextpdf.html2pdf.attach.impl.tags.DivTagWorker unable to process com.itextpdf.html2pdf.attach.impl.tags.ImgTagWorker
Any idea what could be wrong? Here is the template that contains the image already:
<!DOCTYPE html>
<html>
<head>
<style>
#resume-header {
margin-bottom: 25px;
}
#resume-body {
}
#clear {
clear: both;
}
.header-left {
width: 29%;
height: 160px;
float: left;
}
.header-right {
padding-top: 10px;
width: 70%;
height: 160px;
float: right;
}
.header-right h1,h2,h3 {
text-align: left;
font-family: verdana;
}
.header-right h1 {
color: #4065a3;
font-size: 34px;
margin: 5px 0px 15px 0px;
}
.header-right h2 {
font-size: 22px;
margin: 5px 0px 5px 0px;
}
.header-right h3 {
font-size: 10px
}
.avatar-image {
display: block;
margin-left: auto;
margin-right: auto;
height: 160px;
}
.info {
margin: 0px 20px 0px 0px;
font-family: verdana;
font-size: 10px
}
span.section-header {
color: #507fcc;
font-family: verdana;
font-size: 16px;
margin: 0px 0px 0px 10px;
}
p.section-title {
color: #000000;
font-family: verdana;
font-size: 12px;
}
p.section-subtitle {
color: #9aa3b3;
font-family: verdana;
font-size: 12px;
margin-left: 10px;
}
p.text {
color: #000000;
font-family: verdana;
font-size: 10px;
}
ul.list {
color: #000000;
font-family: verdana;
font-size: 10px;
padding-left: 25px
}
div.web-profile {
margin-top: 10px;
}
div.section-content {
margin-bottom: 20px;
}
div.bottom-border {
border-bottom: 1px solid #507fcc;
}
.primary {
color: #507fcc;
}
.small-top-margin {
margin: 2px 0px 0px 0px;
}
.small-bottom-margin {
margin: 15px 0px 2px 0px;
}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css">
</head>
<body>
<div id="resume-header">
<div class="header-left">
<img src="http://clipartmag.com/image/iron-man-face-drawing-6.png" class="avatar-image">
</div>
<div class="header-right" id="basic-info">
</div>
<div id="clear"></div>
</div>
<div id="resume-body">
<div class="bottom-border" id="education-section">
<i class="fas fa-graduation-cap primary"></i><span class="section-header">Education</span>
</div>
<div class="bottom-border" id="job-section">
<i class="fas fa-briefcase primary"></i><span class="section-header">Work</span>
</div>
<div class="bottom-border" id="skill-section">
<i class="fas fa-pencil-ruler primary"></i><span class="section-header">Skills</span>
</div>
</div>
</body>
</html>
iText has a very high number of bugs. Don't comment on the version you are using, but the resource loader has several problems that must be corrected by overloading it (it doesn't know how to load images from base64, it doesn't know how to load resources with 302 redirection, ...).
In your specific case, the error indicated is:
Unable to retrieve image with given base URI (file:/Users/jklancic/dev/custom/resume/) and image source path (http://clipartmag.com/image/iron-man-face-drawing-6.png)
This suggests that iText is trying to access the address "file:/Users/jklancic/dev/custom/resume/http://clipartmag.com/image/iron-man-face-drawing-6.png". Debug at c.i.s.r.r.ResourceResolver:146 to confirm.
If you are able to upgrade to a new version, try to do so, otherwise you should overload the resource loader to fix it.
Remember, you should determine first the exact problem (currently like a bad base+path combination problem), anyway, I fixed a lot of related problems implementing our custom ITextUserAgent as follows:
final ITextRenderer renderer = new ITextRenderer();
{
final TextUserAgent userAgent = new TextUserAgent(renderer.getOutputDevice());
renderer.getSharedContext().setUserAgentCallback(userAgent);
userAgent.setSharedContext(renderer.getSharedContext());
}
You must to implement your custom TextUserAgent to fix your specific problem (iText is not free now):
public class TextUserAgent extends ITextUserAgent {
public TextUserAgent(ITextOutputDevice outputDevice) {
super(outputDevice);
}
#Override
public ImageResource getImageResource(final String uri) {
final ImageResource legacy = super.getImageResource(uri);
if (legacy != null && legacy.getImage() != null) {
return legacy;
}
return alternativeImageResource(uri);
}
...
I'm trying to scroll this pdf: ifcharts.ml/KSAN.html
I've got this so far:
<section class="features section-padding" id="features">
<div class="container">
<div class="row">
<div class="feature-list">
<h3>San Diego</h3>
<p>Departure</p>
<div>
<iframe class="js/scroll-wrapper.js" src="http://flightaware.com/resources/airport/SAN/APD/AIRPORT+DIAGRAM/pdf" width="600" height="700"></iframe>
<iframe class="js/scroll-wrapper.js" src="https://flightaware.com/resources/airport/KSAN/DP/all/pdf" width="600" height="700"></iframe>
</div>
<p>Approach</p>
<div>
<iframe class="js/scroll-wrapper.js" src="https://flightaware.com/resources/airport/KSAN/STAR/all/pdf" width="600" height="700"></iframe>
<iframe class="js/scroll-wrapper.js" src="https://flightaware.com/resources/airport/KSAN/IAP/all/pdf" width="600" height="700"></iframe>
</div>
</div>
</div>
</div>
</section>
The class="js/scroll-wrapper.js" leads to this:
.scroll-wrapper {
position: fixed;
right: 0;
bottom: 0;
left: 0;
top: 0;
-webkit-overflow-scrolling: touch;
overflow-y: scroll;
}
.scroll-wrapper iframe {
height: 100%;
width: 100%;
}
That is what the the script is meant to run, however it still is not scrolling on iOS.
I also have a problem where it is downloading the code on Android. How can I set it now to download?
Thanks
I'm trying to access static content on a login page jsp and I'm failing to do so.
The security config method I'm using is:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**","/images/**")
.access("hasRole('ADMIN')").and().formLogin()
.loginPage("/user/login").failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutSuccessUrl("/login?logout")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/403");
}
The login page that fails to load images and static resources is:
<%#include file="../include/include.jsp"%>
<%#include file="../decorators/tbs_imports.jsp"%>
<html>
<head>
<title><s:message code="title"></s:message></title>
<style>
html,body {
background-color: #eee;
}
body {
padding-top: 5px;
}
.content {
width: 300px;
}
/* The white background content wrapper */
.container>.content {
background-color: rgba(113, 121, 225, .15);
padding: 15px;
margin: 0 -20px;
-webkit-border-radius: 10px 10px 10px 10px;
-moz-border-radius: 10px 10px 10px 10px;
border-radius: 10px 10px 10px 10px;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
}
.login-form {
margin-left: 70px;
}
</style>
<script type="text/javascript">
window.onload = function() {
document.login.j_username.focus();
}
function changeFlag() {
var lang = $("#langDrop option:selected").text();
if (lang == 'Portugues') {
$('#flag').attr('src', '../images/br.png');
}
if (lang == 'English') {
$('#flag').attr('src', '../images/en.png');
}
if (lang == 'Espanol') {
$('#flag').attr('src', '../images/es.png');
}
}
</script>
</head>
<body>
<div style="display: block; margin-left: auto; margin-right: auto"
class="container">
<div style="padding-bottom: 5px">
<img
style="padding-top: 10px; display: block; margin-left: auto; margin-right: auto"
src="${pageContext.request.contextPath}/images/logo_pims_scf_grande.png" />
</div>
<c:if test="${not empty duplicated_user}">
<div
style="display: block; margin-left: auto; margin-right: auto; text-align: center"
class="content alert alert-error">
<strong><s:message code="login-duplicate-user" /></strong>
</div>
</c:if>
<br /> <br />
<c:if test="${not empty session}">
<div
style="display: block; margin-left: auto; margin-right: auto; text-align: center"
class="content alert alert-error">
<strong><s:message code="session-maxLimitReached" /></strong>
</div>
</c:if>
<c:if test="${not empty corrupted}">
<div
style="display: block; margin-left: auto; margin-right: auto; text-align: center"
class="content alert alert-error">
<strong><s:message
code="session-value-corrupted-in-the-database" /></strong>
</div>
</c:if>
<c:if test="${empty session}">
<c:if test="${empty corrupted}">
<div style="display: block; margin-left: auto; margin-right: auto"
class="content">
<div class="row">
<div class="login-form">
<h4 style="padding-bottom: 10px">Login</h4>
<form id="j_acegi_security_check" onsubmit="return true;"
name="login"
action="${pageContext.request.contextPath}/j_acegi_security_check"
method="POST">
<fieldset>
<div class="clearfix">
<input style="height: 25px;" id="username" name="j_username"
type="text" placeholder="Username">
</div>
<div class="clearfix">
<input style="height: 25px;" name="j_password" id="password"
type="password" placeholder="Password">
</div>
<br>
<button class="btn btn-primary" type="submit">
<s:message code="join" />
</button>
</fieldset>
</form>
</div>
</div>
</div>
</c:if>
</c:if>
</div>
</body>
</html>
The WebContent folder structure is:
WebContent
- css
- images
- js
- META-INF
- WEB-INF
- classes
- jsp
- lib
- tags
- index.jsp
- web.xml
Since this application is annotations driven, the web.xml file is blank. And index.jsp redirects to /jsp/user/login.jsp.
Any ideas how to solve this issue?
Thanks in advance.
I started learning javascript and i have a question with a webpage that i created. The webpage is a login page that shows some tableau reports when logged in. I need to create a remember me checkbox just like any other website like gmail or salesforce. I have copy pasted the codes below.
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%
ServletContext context = getServletContext();
String app = context.getInitParameter("appName");
String errorMessage = "";
if ( session.getAttribute("error-message")!=null){
errorMessage = (String) session.getAttribute("error-message");
}
%>
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title><%=app%> - Please login</title>
<link href="styles/bootstrap-theme.min.css" rel="stylesheet">
<link href="styles/bootstrap.min.css" rel="stylesheet">
<link href="styles/sidebars.css" rel="stylesheet">
<link rel="shortcut icon" href="img/favicon.ico">
<style type='text/css' media='screen'>
body {
font-family: Tahoma;
font-size: 12px !important;
padding-top: 40px;
padding-bottom: 40px;
background-color: #fff;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.navbar{
border-color: #ccc;
}
.alert-warning{
margin-top: 15px;
}
.validation-summary-errors{
font-family: Tahoma !important;
font-size: 12px !important;
color: #b94a48;
margin-top: 35px;
margin-bottom: -15px;
}
.col-md-8{
padding-left: 5px;
}
/* .navbar-inverse{
border-color: #ccc;
background: #ddf0f8; Old browsers
background: -moz-linear-gradient(top, #ddf0f8 0%, #ffffff 63%); FF3.6+
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ddf0f8), color-stop(63%,#ffffff)); Chrome,Safari4+
background: -webkit-linear-gradient(top, #ddf0f8 0%,#ffffff 63%); Chrome10+,Safari5.1+
background: -o-linear-gradient(top, #ddf0f8 0%,#ffffff 63%); Opera 11.10+
background: -ms-linear-gradient(top, #ddf0f8 0%,#ffffff 63%); IE10+
background: linear-gradient(to bottom, #ddf0f8 0%,#ffffff 63%); W3C
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ddf0f8', endColorstr='#ffffff',GradientType=0 ); IE6-9
}*/
</style>
</head>
<body>
<div class="navbar navbar-fixed-top" role="navigation">
<div class="navbar-header">
<img class="logo" src="img/Nexius_logo.png"/>
</div>
</div>
<div class='inner col-md-8'>
<%=errorMessage%>
<form action='LoginServlet' method='POST' id='loginForm' class='form-horizontal' role='form' autocomplete='off'>
<h4 class="form-signin-heading"> </h4>
<div class="form-group">
<label for='username' class='col-md-2 control-label'>User name</label>
<div class="col-md-4">
<input type='text' class="form-control" name='user' id='username' />
</div>
</div>
<div class="form-group">
<label for='password' class='col-md-2 control-label'>Password</label>
<div class="col-md-4">
<input type='password' class="form-control" name='pwd' id='password' />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-default" type="submit">Login</button>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10"><div style="position: absolute; top: -45px; left: 100px; width: 240px;">
<input onClick="checkCookie()" type="checkbox" value="Remember me">Remember username<br>
</div>
</div>
</form>
</div>
<script type='text/javascript'>
function setCookie(cname,cvalue,exdays)
{
var d = new Date();
d.setTime(d.getTime()+(exdays*24*60*60*1000));
var expires = "expires="+d.toGMTString();
document.cookie = cname+"="+cvalue+"; "+expires;
}
function getCookie(cname)
{
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++)
{
var c = ca[i].trim();
if (c.indexOf(name)===0) return c.substring(name.length,c.length);
}
return "";
}
function checkCookie()
{
var user=getCookie("user");
if (user!=="")
{
document.getElementById("username").value = user;
}
else
{
if (user!=="" && user!=null)
{
setCookie("user",user,30);
}
}
}
</script>
</body>
</html>
Mostly the upper part is just CSS. In the below part i have writtten the codes to get the username on the text box and pass it to the setcookie function below. So i need it like an usual page like when remember username check box was checked, the username should show up when the page is opened, but for me what it does is, when i open the webpage only when i click on the "remember username" checkbox the username pops up in the username textbox. Now sure what to do about this? Can someone please help me?
You're checking for cookies only when user clicks on the remember me button. You need to check for cookie on document load, for instance.
Add onload handler on body tag this way: <body onload=checkCookie()>. You need to also remove onClick="checkCookie()" from your remember me button.