Генерация PDF в формате ColdFusion — другие варианты cfdocument

Мне просто интересно, есть ли другие варианты использования <cfdocument>, которые могут использовать API веб-комплекта для ColdFusion.

Или, если он доступен на Java, но имеет красивую оболочку ColdFusion, чтобы сделать его проще, чем прорабатывать все тонкости java.


person user125264    schedule 15.01.2014    source источник
comment
Какую версию ColdFusion вы используете?   -  person jk.    schedule 15.01.2014
comment
Достаточно высокий, чтобы иметь тег cfpdf?   -  person Dan Bracuk    schedule 15.01.2014


Ответы (2)


Я захожу под капот и использую iText. Делая это, я создал очень надежную структуру печати (для печати форм) и структуру отчетности (табличные отчеты). Я настраивал его годами, он без проблем может генерировать PDF-файлы с сотнями тысяч строк. Он может работать с 4 детьми и имеет множество функций/настроек. Извините, что так широко. Если вы пойдете по этому пути, я мог бы помочь с особенностями.

Я использую JavaLoader (http://javaloader.riaforge.org/) в своем onApplicationStart для загрузки iText (и другие банки, которые мне нужны в моем приложении)...

<!--- note, this is actually a harcoded UUID value --->
<cfset MyUniqueKeyForJavaLoader = "1111-2222-3333444455556666">
<!--- if we have not already created the javaLoader --->
<cfif not structKeyExists(server, MyUniqueKeyForJavaLoader)>
    <!--- construct an array containing the full path to the jars you wish to load --->
    <cfset pathArray = arrayNew(1)>
    <cfset arrayAppend(pathArray, expandpath('jars/iText-2.1.3.jar'))>
    <!---<cfset arrayAppend(pathArray, expandpath('jars/iText-5.0.6.jar'))>--->
    <cfset arrayAppend(pathArray, expandpath('jars/IDADataMatrix.jar'))>
    <cfset arrayAppend(pathArray, expandpath('jars/LinearBarCode.jar'))>
    <cfset arrayAppend(pathArray, expandpath('jars/barcodeencoder.jar'))>
    <cfset arrayAppend(pathArray, expandpath('jars/sshcommandexecutor.jar'))>
    <!--- <cfset arrayAppend(pathArray, expandpath('jars/jsch-0.1.40.jar'))> --->
    <cflock scope="server" type="exclusive" timeout="10">
        <!--- verify again the javaloader was not already created --->
        <cfif not StructKeyExists(server, MyUniqueKeyForJavaLoader)>
            <cfset server[MyUniqueKeyForJavaLoader] = createObject("component", "javaloader.JavaLoader").init(pathArray)>
        </cfif>
    </cflock>
</cfif>

Затем, в структуре отчета, вот как вы начнете инициализировать все. (это всего лишь небольшой фрагмент, там гораздо больше, чем идет в этом, но этого должно быть достаточно, чтобы вы начали дурачиться, если решите).

<cfscript>
    pathAndFile      = request.reportDir.fpath&request.reportDir.pdfFile;
    session.reports[libRptId].pathAndFile = pathAndFile;
    loader           = server['1111-2222-3333444455556666']; //Our iText version which currently is 2.1.3 (yes, we need to update soon)
    document         = loader.create("com.lowagie.text.Document");
    PdfWriter        = loader.create("com.lowagie.text.pdf.PdfWriter");
    FileOutputStream = createObject("java", "java.io.FileOutputStream");
    myFile           = CreateObject("java","java.io.File").init(pathAndFile); //Only used for getting the file size to display on screen in real-time as the pdf is being generated
    Color            = createObject("java", "java.awt.Color");
    element          = loader.create("com.lowagie.text.Element");
    Chunk            = loader.create("com.lowagie.text.Chunk");
    PageSize         = loader.create("com.lowagie.text.PageSize");
    HeaderFooter     = loader.create("com.lowagie.text.HeaderFooter");
    Rectangle        = loader.create("com.lowagie.text.Rectangle");
    Paragraph        = loader.create("com.lowagie.text.Paragraph");
    PdfPCell         = loader.create("com.lowagie.text.pdf.PdfPCell");
    PdfPTable        = loader.create("com.lowagie.text.pdf.PdfPTable");
    Phrase           = loader.create("com.lowagie.text.Phrase");
    Font             = loader.create("com.lowagie.text.Font");
    FontFactory      = loader.create("com.lowagie.text.FontFactory");
</cfscript>

<!--- Define our different fonts --->
<cfset fontTitle       = FontFactory.getFont("Arial", 10,                 Font.BOLD,       Color.BLACK)>
<cfset fontSubRptTitle = FontFactory.getFont("Arial", 10,                 Font.BOLDITALIC, Color.BLACK)>
<cfset fontStandard    = FontFactory.getFont("Arial", 8,                  Font.NORMAL,     Color.BLACK)>
<cfset fontHeader      = FontFactory.getFont("Arial", 9,                  Font.NORMAL,     Color.GRAY)>
<cfset fontFooter      = FontFactory.getFont("Arial", 9,                  Font.NORMAL,     Color.GRAY)>
<cfset fontColHeader   = FontFactory.getFont("Arial", rpt.fontsizeLabel,  Font.BOLD,       Color.BLACK)>
<cfset fontData        = FontFactory.getFont("Arial", rpt.fontsize,       Font.NORMAL,     Color.BLACK)>

<cfset marginTop    =  round(72 / (100 / (rpt.marginTop * 100))) >
<cfset marginright  =  round(72 / (100 / (rpt.marginright * 100))) >
<cfset marginbottom =  round(72 / (100 / (rpt.marginbottom * 100))) >
<cfset marginleft   =  round(72 / (100 / (rpt.marginleft * 100))) >

<!--- Page Setup (PageSize and Margins)  For the margins 18 = .25inches --->
<cfif rpt.pagetype eq "letter">
    <cfif rpt.orientation eq "portrait">
        <cfset document = document.init(PageSize.LETTER, marginleft, marginright, marginTop, marginbottom)>
    <cfelse><!--- Landscape --->
        <cfset document = document.init(PageSize.LETTER.rotate(), marginleft, marginright, marginTop, marginbottom)>
    </cfif>
<cfelseif rpt.pagetype eq "legal">
    <cfif rpt.orientation eq "portrait">
        <cfset document = document.init(PageSize.LEGAL, marginleft, marginright, marginTop, marginbottom)>
    <cfelse><!--- Landscape --->
        <cfset document = document.init(PageSize.LEGAL.rotate(), marginleft, marginright, marginTop, marginbottom)>
    </cfif>
<cfelseif rpt.pagetype eq "ledger">
<!--- We found that ledger logic is backward from letter and legal. Long edge is portrait 11 X 17 and landscape mode = 17 X 11 --->
    <cfif rpt.orientation eq "portrait">
        <cfset document = document.init(PageSize.LEDGER.rotate(), marginleft, marginright, marginTop, marginbottom)>
    <cfelse><!--- Landscape --->
        <cfset document = document.init(PageSize.LEDGER, marginleft, marginright, marginTop, marginbottom)>
    </cfif>
</cfif>
<cfset writer = PdfWriter.getInstance(document, FileOutputStream.init(pathAndFile))> <!--- Init the variable "document" that we write to --->
person gfrobenius    schedule 15.01.2014
comment
@user125264 user125264, я добавил больше деталей, чтобы ответить. - person gfrobenius; 15.01.2014

Мы используем небольшое приложение под названием wkhtmltopdf, которое позволяет создавать PDF-файлы из любой HTML-страницы. Он работает с командной строкой, поэтому вы можете использовать <cfexecute> для его запуска. Я также использую следующий код, чтобы убедиться, что PDF-файл полностью сформирован перед его выводом:

<cfset truePDF = "false">
<cfloop condition="NOT truePDF">
    <cfif fileExists("#pathname##filename#")>
        <cffile action="read" file="#pathname##filename#" variable="pdfContent">
        <cfif findNoCase('%%EOF',right(pdfContent,1024)) GT 0>
            <cfset truePDF = "true">
        </cfif>
    </cfif>
</cfloop>
<cfoutput>#pdfContent#</cfoutput>
person Sander    schedule 07.05.2015