How do I get phantomJS to generate pdf that is just a single page that contains my page? - phantomjs

I am trying to create a pdf from a webpage using phantomJS. I want the pdf to just be a single page long that is the same height as my webpage. If I don't set paperSize or viewportSize at all then it creates a page that is almost the right height, it is just a little short by about 100px. If I detect page height and use that to set viewportSize I have the exact same problem, it's short by about 100px. Is there a way to get phantomJS to just create a pdf based on the webpage's size? I want it to be exact because the page is a dark colour and it looks really bad to have a big white block at the end of the page (which is what is there if I add a constant to viewport height to make it fit everything in one page).
My code to find height(Note: the height is the same whether I use body or the classname below to find it):
var size = page.evaluate(function() {
var height = $('.export-athlete-detail-report').outerHeight(true);
return {width: 700, height:height};
});
page.paperSize = size;
page.render(reportFile);

Related

How to set height of WebView according to the length of content in Nativescript-Vue?

Update: I used HtmlView and yes, the height is dynamic with the content,
but it seems like not support <img />
I'm currently using WebView to render the markdown content as below
<WebView :src="marked_content" height="1200px" margin="20dp" />
The result is fixed at 1200px with scrollBar as expected, but what I actually want to do is to render the whole markdown content with various height and without scrollBar.
Anyone may help, please?
PS: Any other methods which may render markdown content is welcome! Thank you!
Do you have control over the website, if Yes you can do this
https://discourse.nativescript.org/t/dynamic-webview-height/4215/2?u=manojdcoder
I have worked out how to do this without plugins.
There is a solution above which appends the URL with a hash containing the page height. It didn't work for me because I'm adding HTML code directly.
For example
src="<p>blah blah</p>"
This is a plain JS solution, so you'll have to rework it to get it working in Vue / Typescript.
Give your WebView an id, do not set the height, and add the "loaded" and "loadFinished" handlers.
For the loaded handler.
platformModule = require("tns-core-modules/platform");
var webViewSrcObj = {};
exports.webViewLoaded = function(webargs){
if(platformModule.isAndroid){console.log("IS ANDROID!!!"); return false;}
webview = webargs.object;
if(webview.height == "auto"){
webViewSrcObj[webview.id] = webview.src;
webview.src += '<script>function getPageHeight(){if(document.documentElement.clientHeight>document.body.clientHeight){height = document.documentElement.clientHeight}else{height = document.body.clientHeight}; ph = document.getElementById("pageHeight"); window.location = "pageHeight.html?height="+height;} setTimeout(getPageHeight, 1);</script>';
}
}
It checks the platform, and returns false if it is Android (Android works fine already).
Then it checks if the height is set to "auto" (which is default).
if it is set to auto, it will copy the HTML content. I'll explain more about this later. It then appends the html with some JavaScript code that calculates the view height, and then redirects to an empty page. It does this in order to use the query string for the page height. Make sure that page exists in your app folder to avoid any page not found errors!
Then for the onLoadeFinished handler...
exports.webViewLoadFinished = function(webargs){
if(platformModule.isAndroid){
console.log("IS ANDROID!!!"); return false;
}
webview = webargs.object;
if(webargs.url.indexOf("?height") > -1){
height = (webargs.url).split("?height=");
height = height[1].substr(0, height[1].length)/1;
webview.height = height; webview.src = webViewSrcObj[webview.id];
}
}
This will check to see if the query string height value exists.
If so it uses the height value to set the height of the webview.
And finally it adds the HTML content that was copied in the onLoaded handler.
My initial testing works well even with multiple webviews in a page.
I haven’t done extensive testing, but it might help to increase the setTimeout time if you experience any problems.
If anyone is able to improve this solution, please share your results.

Image not showing up in itextsharp generated html to pdf document when Height/Width are added in style

I am working on dynamic HTML to PDF document and using ckeditor to write HTML and then itextsharp 5.5.10 to generate downloadable PDF from it. Below is the code I am using
string htmlText = "some basic HTML I wrote in ckeditor 4.0 and save in my DB to retrieve later"
StringReader sr = new StringReader(htmlText);
Document pdfDoc = new Document(PageSize.A4, 0, 0, 0, 18f);
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
// instantiate the custom PdfPageEventHelper
MyPageEventHandler e = new MyPageEventHandler()
{
ImageHeader = imageHeader
};
writer.PageEvent = e;
pdfDoc.Open();
XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
pdfDoc.Close();
// Auto Download option
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=Proposal-" + pid + ".pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Write(pdfDoc);
Response.End();
Now everything is working fine, thanks to this great library itextsharp however sometimes its not adding few images to PDF file.
During debugging I found that variable htmlText has same input HTML that I saved using ekeditor and it contains all img tags too but still some images are not showing up in PDF.
Below are few tags in my HTML
<img alt="" src="http://www.mydomain/fullpath/13101571jjc-banner.png" />
<img alt="" src="http://www.mydomain/fullpath/0c1bc6fbchart-1.png" style="width:400px" />
<img alt="" src="http://www.mydomain/fullpath/f7802520graph1.png" style="height:288px; width:643px" />
<img alt="" src="http://www.mydomain/fullpath/4cd70c03sample_s-l_DISTRIBUTION.jpg" style="height:756px; width:1056px" />
and 4th image is not showing up in my PDF.**
I understand that it may have something to do with Height and Width attribute on img tag but I am not able to solve it.
Note : image show up properly when I remove either Height or Width or both attributes from img tag. But actual user using my code won't do that every time they add a new image in HTML so I am looking for a proper solution here.
Thank you in advance for any suggestion and solution.
On one hand the style attribute of your problem image looks like this:
style="height:756px; width:1056px"
On the other hand you use an A4 sized document
Document pdfDoc = new Document(PageSize.A4, 0, 0, 0, 18f);
and an A4 page has a width of about 8.27in which at 96px per inch are about 794px.
Thus, an A4 page simply is not width enough for a 1056px wide image!
So to accommodate the image you can either
change the document size to something wider, or
before feeding the HTML into iTextSharp apply a preprocessing step which checks it for inappropriate attribute values and fixes them, or
change the HTML generation process to not produce such inappropriate attribute values to start with.
In an additional comment you asked
What should be the max-width and max-height of an image in order to get it printed correctly?
Considering that you explicitly set the left, right, and top margin to 0 and the bottom margin to 18 user units (by default a user unit is a 1/72 in), the maximum image width will likely be about 794px and the maximum image height about (1122 - 18 * 96 / 72)px = 1098px. To be sure subtract yet another few pixels.
This of course depends on your HTML not adding additional margins or cell borders or whatever around the image...

Is it possible to have a sticky header, scrolling to anchors all in a responsive layout?

I have a responsive layout and I am using sticky.js for my header. This seems to be working minus a few glitches that I can live with. But my anchors are always off (I am using smooth scrolling). I am not sure how to compensate for the sticky header when scrolling to an anchor when the responsive layout is constantly changing the width and height?
Unfortunately there is not a whole lot you can do with straight-CSS which won't distort your design. To tackle this issue in previous projects, I have used jQuery to handle these types of scrolling/anchor issues.
What You Have Now: <a> tags that look for id's on the page. The problem is this: when the site goes responsive, those anchor tags don't line up so nicely with your DOM layout.
My Solution: To give you the high level concept - I used jQuery to modify the ID positions on the fly. Say you click on a link when the site is full-size, and everything is fine. jQuery is not needed here. Now say that when you click that same link when the site was scaled to about the 768px-width range (iPad portrait): then my anchors might look as if they were about 100px off (for example). I wrote a bit of jQuery to handle this: "If the width is __, then offset the anchor ID's by ___px."
I would recommend using JS to account for the difference at time-of-scroll, rather than trying to artificially alter the height property of your anchor tags. Here's a function that might work for you, using pure JS:
adjustScroll = function () {
// Sticky nav selector (you'll have to provide your own selector)
const nav = document.querySelector('header>nav');
if (location.href.indexOf("#") >= 0) {
// Find the name of the anchor
let n = location.href.substr(location.href.indexOf("#")+1);
// Find the anchor by name, if it exists
let a = document.querySelector('a[name="'+n+'"]');
if (!a) {
return;
}
// Set y value as y-value of the anchor, offset by the header height
let y = a.offsetTop;
y -= nav.height + 10;
// Scroll to the y position
window.scrollTo(0, y);
}
}
// Call it wherever you need to call it
adjustScroll();
Examples of where to call it might be on a DOMContentLoaded event, or on an onclick event for anchor tags.

Supersized Slideshow below Header

I'm using the supersized jquery plugin in order to display a fullscreen background slideshow.
Look at this website (it's not my own but I'm using the same structure):
http://mysampleconcept.com/situs4/
As you can see (for example if you give the header some opacity) the images begin at the top of the body.
But I want them to begin below the header (so that the header doesn't cover the top of the image).
If you give the supersized LIs for example top: 100px; the whole image moves down so that the bottom of the image disappears below my footer.
So that's not the solution I want.
So all in all which I need is the image to stretch to the biggest size it can, while still being inside the window not stretching over the top 100px nor bottom.
How can I do this?
Sorry, my English is not the best...
I found this solution but I don't know how to implement it: https://stackoverflow.com/a/12889088/1981981
You can use the solution offered in the question you refered to as a starting point. Just place it right below the $.supersized() inside your document ready function.
Since you want a top offset, we have to modify the top value aswell. I modified the snipped to suit your needs:
var portfolioSize = function() {
var headerOffset = 100;
$('#supersized').css({
height: $(window).height() - headerOffset,
top: headerOffset + 'px'
});
};
portfolioSize();
$(window).resize(function() { portfolioSize(); });
I changed the $(window).load Event to a direct call, since we place the code inside the document ready function.
Don't forget to modify the CSS for positioning as mentioned in the other answer (https://stackoverflow.com/a/12889088/860205).

How to resize image to a fixed height and width without losing aspect ratio in winjs?

I have an image area in my application with width:530px and height:510px. I want to place images in that area but the images comes in different different sizes. how to crop or scale the image without losing aspect ratio to fill that area. Is there any native methods available in winjs?
You have a few options for that.
One is to use the ViewBox control that WinJS provides you. The ViewBox can only have a single child (so you would have your tag as its only child perhaps or a div that contains your img) and it will scale that child (using CSS transforms) up to fit into its container (without changing the aspect ratio). It's pretty slick.
Another option is to set the image as the CSS background-image property of a container (such as a div) and set the background-size property to contain. This will stretch the image up to the size of the container.
A final option that you have to resort to if your case is a bit special is not such a bad option after all. In the updateLayout method of your page, you can refer to the element and explicitly set its CSS properties to fit. At that point you'll know all about the layout and can easily do the math to figure out what size image should be. Here's some code from one of my projects where I do this. Notice that I'm comparing the aspect ratio of the screen and the image to determine whether I should size to the width or the height. Unlike your situation (I'm guessing), my code makes sure the image fills the screen and excess is clipped. I'm guessing you want your img to be contained.
function setImagePosition() {
var img = q(".viewCamera #viewport img");
if (outerWidth/outerHeight > img.naturalWidth/img.naturalHeight) {
img.style.width = format("{0}px", outerWidth);
img.style.height = "";
img.style.top = format("{0}px", (outerHeight - img.clientHeight) / 2);
img.style.left = "0px";
} else {
img.style.width = "";
img.style.height = format("{0}px", outerHeight);
img.style.top = "0px";
img.style.left = format("{0}px", (outerWidth - img.clientWidth) / 2);
}
}
Hope that helps!
Are you referring to scaling HTML images? If so, you can set either one, width or height. Whichever you set, the other will scale and keep image aspect ratio.