Generating PDFs in ColdFusion - pdf

I have an application for customer and product management that has many screens/pages. I would like certain pages to be printable and exportable to PDF.
To print a document, its a simple case of providing a CSS stylesheet for #Print media which strips a lot of the regular styling. However, when generating the PDF I noticed the <cfdocument> and <cfhtmltopdf> tags both want the an entire HTML page to render (including <head> tags).
This means that it doesn't recognise the purpose of the PDF as being for print and doesn't pick up the #Print styles. Currently I'm having to make a seperate makepdf.cfm page and repeat the HTML of the page I want to export along with including ONLY the print CSS stylesheet.
This seems a bit crazy because I'll have to update the makepdf.cfm page each and everytime I change a main application screen that can be printed/exported to pdf.
Is there a better way to achieving what I'm trying to do?

I am not sure how your CSS is organized, but I had a similar situation where I needed to print various content off the screen. My solution was to use an AJAX call (CFAJAXPROXY) in Javascript to a CFC in order to set a CF session variable with the DIV content and then call my print page which will output the content with the cfhtmltopdf tag. My experience has been that the CSS must be included in within whichever PDF generation tag you are using.
For example:
<div id="myContent">content on my page to print</div>
And a button to print
<button onclick="printContent('myContent')">Print</button>
The onclick calls the following in the Javascript:
var printContent = function(_contentDiv){
var _content = $('#' + _contentDiv).html();
var _setContent = _cfc.setContent(_content);
window.location.href = 'printPage.cfm';
}
The "_cfc" is defined in a cfajaxproxy call.
The CF function that's going to get called looks something like the following:
<cfcomponent>
<cffunction access="remote" name="setContent" returntype="string">
<cfargument name="_content" required="yes" type="string">
<cfset session.content = _content>
<cfreturn "whateveryouwant">
</cffunction>
</cfcomponent>
And the printPage.cfm might look like this (I use Bootstrap as my CSS):
<cfhtmltopdf>
<link href="css/bootstrap.css" rel="Stylesheet" type="text/css"></link>
<cfoutput>#session.content#</cfoutput>
</cfhtmltopdf>
This is obviously a bare bones solution, but it works. I would imagine that if you needed different CSS pages, you could set the HREF value in the link tag as a session parameter as well

Assuming you're using a link tag in the head you can try to use cfinclude inside style tags to include the css file. cfdocument seems to do better with inline styles.
I ended up passing a url flag pdf=0/1, then in the template simply add a cfif around whatever content you want to toggle.
I'm trying to get it to recognize FontAwesome and Google Charts at this point. Seems to help so far.

Related

I need to add a js file to be able to manipulate html

I need to be able to add a js file to be able to manipulate the html? I tried to add something similar to what is done in the assets.yml by loading the styles.css, but I did not have the expected result, and I do not understand how else I could do it.
There is a new Quick Start Guide in a JavaScript tutorial that has the exact example you are asking for:
https://doc.oroinc.com/frontend/javascript/js-quick-start/
You can do JavaScript coding inline, I would suggest making a separate file for it though, just like you do with a .css file. A .js file is called with a <script> tag instead of <link> in your HTML document.
How to do it
Make a new file called main.js inside your folder
Call it with the <script> tag in your HTML document, usually just before the closing </body> tag.
Make an element and manipulate it - this example is the p element that has the ID #change. One way to do it is with document.querySelector. You can do it with a classname as well if you prefer.
I'll let you do the rest.
document.querySelector('#change').innerHTML =
<p id="change">Change me</p>
<script src="main.js"></script>

How to break page on pdf with dynamic content in jsreport

I have a js report pdf with header and footer with dynamic content.But content are overlap on next page.Page break not working on it.
i know this might be old but you can add
<div style="page-break-before: always;"></div>
before any div you want to break the page after

Exclude menu from content extraction with tika

I generate html documents that contain a menu and a content part. Then I want to extract the content of these document to feed it to a lucene index. However, I would like to exclude the menu from the content extraction and thus only index the content.
<div class="menu">my menu goes here</div>
<div class="content">my content goes here</div>
what is the simplest way to achieve this with apache tika?
As a more general solution (not just for you specific menu) I would advise looking at boilerpipe that deals with removing uninteresting parts from pages (menus, navigation etc).
I know it can be integrated in Solr/tika, have a look and you probably can integrate it in your scenario.
Have a look at this post which specifies how to handle DIVs during the HTML parse, by specifying whether they are safe to parse or not, in which case its ignored. For your problem, you could have some logic in the override methods which ignore only DIV elements with attribute value "menu" (i.e. tell TIKA parser this DIV is unsafe to parse).
You can parse the html with a parser to a xhtml dom object an remove the div tag cotaining the attribute class="menu".

Creating a PDF in ColdFusion?

How can dynamic HTML be put into a PDF using ColdFusion?
This is in relation to my question about getting IE to work properly with a CFDIV.
What I am trying to do is something similar to this
<cfdocument
name="table"
format="PDF">
foo
<cfdiv id="content" bind="cfc:TestCFC.displayTable({filters})"></cfdiv>
bar
</cfdocument>
however when I open my PDF document, I only see
foo
bar
I would like a solution that uses the CFDIV with the bind, however if that is not an option than any solution will do.
You can't use bind parameters for pdfs because the bind parameters are executed via AJAX on the client. You'll need to do something like this instead:
<cfdocument name="table" format="PDF">
foo
<cfdiv id="content"><cfoutput>#TestCFC.displayTable({filters})#</cfoutput></cfdiv>
bar
</cfdocument>
And you'll need to get the filters argument in there via some other method than a bind to another element. Possibly a FORM or URL variable when the user clicks the link or button to generate the PDF.

Safe hidden text in HTML?

I need to have some hidden text in HTML to parse as text when i read an actual HTML file
I used to include my text in hidden div using style but i knew that may record us as spammers in SEO
.hideme {
position : absolute;
left : -1000px;
}
Can i have this content as commented text in the HTML ?
will that be safe as i know that SEO crawlers ignores the comments in HTML
<!-- my hidden text -->
Please advice
The search engines only care about hidden text when it is used to manipulate a page's rankings. Typically this is defined as content that is presented to the search engines that is not presented to users. So if you hide text so users can't see it but crawlers can you will find yourself having issues with Google. An example of when hiding text is good is when you use display:none to hide dynamic content and then use JavaScript or CSS to display the content when an action is performed (i.e. mouseover, etc).
If you place this extra content within comments as you suggest in your question you will be fine as this content is not available to users and search engines ignore comments.
Try to avoid "hide" in naming your CSS class.
But the best way is to avoid hidden text by finding easy and creative ways to add the text to the content of a web-page without seeming like spam.
You can't parse html comments so instead use a hidden field:
<input type="hidden" value="my text" name="my_hidden_field/>
Some people for SEO doing this :
.hideme {
width:0px;
overflow:hidden;
text-indent:-99999px
}
Why you do not use <meta> tags ?