Accessible PDF's from Coldfusion 2021 - pdf

I've been looking everywhere, and can't find a suitable answer. We are generating PDF's on the fly for a job board. People click on a job, and have an option to download a PDF version of the job posting. We currently have everything running just fine with cfdocument, but our client is hoping to get the website to 100% compliant with WCAG 2.1.
Currently, i've tried using cfdocument, then using cfPDF to set things like title, as mentioned by Raymond Camden in ColdFusion 8: Working with PDFs (Part 2) but this doesn't seem to work anymore as the downloaded documents don't keep the set information.
The other issue is the PDF isn't marked as a PDF (apparently a flaw with cfdocument Adobe has no plans to fix).
We've tried cfhtmltopdf, but we require headers and footers for each page, and as many have pointed out on various forums, Adobe's implementation is a joke.
So, my question now is, what is the best route to creating a fully compliant PDF from Coldfusion (3rd party options are a route we are willing to take if needed) Ideally we would want the direct download like CFDocument, but we are not opposed to having a physical file created for each job posting if it means having a compliant PDF.
Our code, after all the body content, looks as follows (again this doesn't set the title, language or tag as PDF, and doesn't allow alt tags on our images for some reason).
<cfheader name="Content-Disposition" value="attachment;filename=filename.pdf">
<cfheader name="Content-Language" value="#session.language.code#" />
<cfdocument name="myPDF" format="pdf" orientation="portrait" pageType="custom" pageWidth="8.5" pageHeight="10.75" unit="in" localUrl="yes" marginbottom="1.5" margintop="1" marginleft="0.25" marginright="0.25">
***
***
***
***
<cfset PDFinfo=StructNew()>
<cfset PDFinfo.Title="#returnStruct.JobDetails.title#">
<cfset PDFinfo.Language = 'EN-US' />
<CFIF returnStruct.JobDetails.anonymous EQ 0>
<cfset PDFinfo.Author="#returnStruct.JobDetails.Organization#">
<CFELSE>
<cfset PDFinfo.Author="Employment Agency Name">
</CFIF>
<cfpdf action="setInfo" source="myPDF" info="#PDFinfo#">
<cfpdf action="write" source="myPDF" name='myPDF' version="1.4">
<cfcontent type="application/pdf" reset="true" variable="#toBinary(myPDF)#">

Related

coldfusion cfcontent want to offer open file but not download

In ColdFusion I have code to open or download a file:
<cfif FileExists('#session.exploc#/#attname#')>
<cfset typeatt = FilegetMimeType('#session.exploc#/#attname#')>
<cfheader name = "Content-Disposition" value="attachment;#session.exploc#/#attname#">
<cfcontent type="#typeatt#" file="#session.exploc#/#attname#">
</cfif>
This gives a standard open/download window.
I would prefer a window which just allows the user to open the file, and does not provide a download. Is there a way to do that?
Alternatively, I am happy to open the file in the browser, but since I don't know the filetype in advance I'm not sure how to do that.
This is not a function of <cfcontent> per-se. All <cfcontent> handles is the MIME-type of the response, the content of it (it can reset it for example), and a few other bits and pieces. It's all about the nature of the content returned by the CFML server.
This is all fairly clear in the docs for <cfcontent>:
Some file types, such as PDF documents, do not use executable code and can display directly in most browsers. To request the browser to display the file directly, use a cfheader tag similar to the following:
<cfheader name="Content-Disposition" value="inline; filename=name.ext">
IE: what you want to be doing is to set the Content-Disposition header with a value of inline to tell the browser to potentially inline the document, if if has the capabilities to do so.

p:media getting rendered differently across browsers

I'm on PF 6.2 and trying to use the p:media component for displaying PDFs.
(I shifted from using pe:documentViewer only because it currently doesn't display digital signatures, since PDF.js doesn't support that feature in the first place).
However, I observe that the look-n-feel of the rendered PDF viewer is different across browsers.
My usage:
<p:media id="pdfVw" height="600" width="800" value="#{viewerController4.pdfDocumentStream}" player="pdf" cache="false">
<f:param name="id" value="#{viewerController4.currentDocId}" />
</p:media>
In the backing bean:
public StreamedContent getPdfDocumentStream() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
} else {
String id = context.getExternalContext().getRequestParameterMap().get("id");
Doc doc = pdfDocMap.get(id);
return new DefaultStreamedContent(new FileInputStream(new File(doc.getDocPath())), "application/pdf", doc.getDocName());
}
}
About the look-n-feel...for example, in Chrome:
* no thumbnail strip for the pages!
* that string "Microsoft word-Dokument1" is coming from the PDF's "title" attribute (I wish I could suppress displaying it !)
In Firefox:
* the thumbnail strip is there
* the digital signature is gone!
* that title string is not there (for me, it's a plus)
* the menus are also completely different compared to Chrome
(In IE, it's even more different)
My client's target browser is Chrome.
If I could somehow suppress that title and start showing the thumbnail strip in Chrome, that would solve my purpose entirely. Any advice?
I came to know....to expect the thumbnail strip in Chrome would be a wrong expectation, while using p:media. This is because, while with p:media, Chrome would use its own PDF viewer and not Adobe's (so, there may not be all Adobe like features available). More here:
https://community.adobe.com/t5/acrobat/adobe-acrobat-features-not-showing-up-in-chrome/td-p/10480323?page=1
On the topic of the title getting displayed on the toolbar, I still couldn't find any solution to easily suppress or soft-modify it, other than editing the title metadata of the PDF itself.
Also, came across this nice document that lists the various <f:param> that can be passed to configure viewers :)
https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf

Why won't my docbook links work when linking to something earlier in the document?

I'm going from docbook to fo to pdf and I need to have text that goes to different parts of the document when clicked. I'm using the following format
<link linkend="M1350424Trace">
<emphasis role="bold">Link To Trace</emphasis>
</link>
Where M1350424Trace is the id of a paragraph. It works how I want it to work when I'm linking to something that comes later in the document but not when it's trying to link to something that comes earlier. Why is that?
Here's the .fo
<fo:basic-link internal-destination="M1350424Trace">
<fo:inline>
<fo:inline font-weight="bold">Link To Trace</fo:inline>
</fo:inline>
</fo:basic-link>
I've reproduced your case with the following input data:
Sample DocBook file with link and xref as a linkage mechanism
link and xref both and the target id are on different pages after rendering.
DocBook 5.1 as a source.
DocBook XSL 1.79.1 - as a stylesheets.
FOP 2.3 as a renderer.
The produced PDF file was tested with xpdf 3.04, Acrobat Reader 7.08 on Linux Debian 9.5
Works as should be: pressing the link moves to the page with a required element (para) with a required id number.
So you need to provide the exact file and exact configuration that raised this strange behavior. You can fill it with a dump data in case your document is under NDA or contains sensitive information, BUT it should be the same in matter of structure and elements within as an original one.
I'll try to reproduce your case.

pe:documentviewer nameddest attribute doesn't work

I'am trying to show a pdf in a p:dialog , but i want to open pdf in a spécific destination, there is my code:
<p:commandLink value="test" oncomplete="PF('dlg').show()"/>
<p:dialog header="Dialog" widgetVar="dlg"
resizable="false"
fitViewport="true">
<pe:documentViewer height="500" width="800"
nameddest="nature"
name="helpImmo.pdf"/>
</p:dialog>
So the pdf is opened but in the first page
NB:when i use the page attribute it works
Attribute nameddest of pe:documentViewer can be used to open PDF in specific named destination which is technically different then bookmark.
To test if your code and project libraries work correctly, download this pdf example, include it into your project and in pe:documentViewer and set, for example, nameddest="Chapter3".
I've tested it with PF 6.1 and PF-extensions 6.1. It works OK on my side and opens requested named destination.
So make sure that
your PDF actually has named destination 'nature' created,
your version of PF-extensions does not have some known issue related to opening named destinations.
Also you can programmatically add named destinations to your PDF with iText java library as described in this example.

CFPDFForm Populate Error - java.lang.NullPointerException: Platform, Locale, and Platform Name must not be null

I've been banging my head against the wall trying to figure out the cause of the error below.
All I'm doing is running this very simple CFPDFFORM to populate a PDF form.
<cfset source = expandPath("Customer.pdf")>
<cfpdfform action="populate" source="#source#">
<cfpdfformparam name="Name" value="John Doe">
<cfpdfformparam name="Address" value="123 Test Cir">
<cfpdfformparam name="City" value="Some City">
<cfpdfformparam name="State" value="Some State">
<cfpdfformparam name="Zip" value="11111">
<cfpdfformparam name="Phone" value="123-456-7890">
</cfpdfform>
I've done a lot of searches and found very few people talking about this error. The one page that I found was ColdFusion CFPDFFORM does not populate PDF form fields. I tried the idea of going through my fonts and looking for corrupted ones. I even used a program called Fix Fonts Folder (http://fix-fonts-folder.en.softonic.com/) which was able to locate some corrupt fonts. But even then, I still get the error. So, I'm desperately looking for an answer.
Just in case, I'm running ColdFusion 10 Update 9 on Windows 7.
Thanks in advance.
I wrote a script that will parse all the font files in c:\windows\fonts and report back on the bad ones:
<cfset fontobj = createobject("java","com.adobe.fontengine.fontmanagement.FontLoader")>
<cfdirectory action="list" directory="c:\windows\fonts" name="fontdir">
<table border="1" style="border-collapse:collapse">
<tr>
<th>Font Name:</th>
<th>Error</th>
</tr>
<cfloop query="fontdir">
<cftry>
<cfset loaded = fontobj.load(createobject("java","java.net.URL").init("file:///C|/windows/fonts/#fontdir.name#"))>
<cfif arraylen(loaded) gt 0>
<cfset dummy="#loaded[1].getPlatformFontDescription()[1].toString()#" >
</cfif>
<cfcatch>
<cfif findnocase("platform",cfcatch.message)>
<tr>
<td><cfoutput>#fontdir.name#</cfoutput></td>
<td><cfoutput>#cfcatch.message#</cfoutput></td>
</tr>
</cfif>
</cfcatch>
</cftry>
</cfloop>
</table>
I had the same issue too right after the installation of CS6.0.
Platform:
CF9.0
Win 7
CS6 (obviously)
Through trial and error, as stated above and a good few restarts of coldfusion I've whittled it down to the following font files that you can uninstall via font manager by going to C:\Windows\Fonts :-
AdobeNaskh-Medium.otf
MyriadArabic-Bold.otf
MyriadArabic-BoldIt.otf
MyriadArabic-It.otf
MyriadArabic-Regular.otf
Hope this helps someone. Took me a fair few hours to fix this "niggle".
The workaround on the reported bug solved the issue. Thanks Miguel-F
The workaround is: "delete all fonts installed with the same date as your creative cloud 6 app installations or uninstall creative could 6"
had the same issue myself.
My solution (which compliments the above correct answer):
Here's the list of fonts that Adobe installs with the Creative Suite 6:
http://www.adobe.com/type/browser/fontinstall/cs6installedfonts.html
Copy all these fonts to the separate folder and remove from the Windows/Fonts directory.
Test CFPDFFORM bit and confirm it's working
Manually add them back.
In my case it turned out none of those fonts were corrupt per se, though probably weren't installed the way Windows like it. Re-installing it manually somewhat fixed the issue.
One more note: I've removed all until MyriadPro (including it) constantly refreshing the page containing CFPDFFORM bit until it worked. So for those trying to get a fast fix, I'd recommend starting with MyriadPro family. It just may turn out it's the one that breaks the things.
Hope this helps someone out!
/////////////// UPDATED 7/02/2014 ///////////////////////////////////////////////////////////////////
It turns out I am not able to comment until certain number of points will be acquired, therefore I'm not able to say how much Jesse Carlton's answer (above) helped me out.
Here's one more step that solved me the bug:
It turns out that some of the Adobe installed fonts have name values as null, hence failing the cfpdfform badly. To find those files use the script that Jesse Carlton created (again, it's above in one of the answers)
At least in my case all those fonts had duplicate values (normal and _0 ones). Normal values were visible and easy to remove using Windows font manager. However, the _0 ones weren't visible.
Download software like FontExpert2014 (or any other font manager for that matter) and locate those files that you couldn't see in the windows font manager.
To check whether all of the corrupt fonts are removed run the script from the step 1 again. When you'll get the empty table, try cfpdfform bit that was failing you previously and all should be good.
*the software from the step 3 was downloaded as evaluation version and did the trick for me.