java - How to adjust the page height to the content height? -
i'm using itextpdf + freemarker project. load , fill html template freemarker , render pdf itextpdf's xmlworker
.
the template is:
<html> <body style="font-family; ${fontname}"> <table> <tr> <td style="text-align: right">${timestamplabel} </td> <td><b>${timestampvalue}</b></td> </tr> <tr> <td style="text-align: right">${erroridlabel} </td> <td><b>${erroridvalue}</b></td> </tr> <tr> <td style="text-align: right">${systemidlabel} </td> <td><b>${systemidvalue}</b></td> </tr> <tr> <td style="text-align: right">${descriptionlabel} </td> <td><b>${descriptionvalue}</b></td> </tr> </table> </body> </html>
and code:
simpledateformat date_format = new simpledateformat("yyyy/mm/dd hh:mm:ss"); string errorid = "error-01"; string systemid = "system-01"; string description = "a short description of issue"; map<string, string> parametersmap = new hashmap<string, string>(); parametersmap.put("fontname", fontname); //valid font name parametersmap.put("timestamplabel", " timestamp:"); parametersmap.put("erroridlabel", " error id:"); parametersmap.put("systemidlabel", " system id:"); parametersmap.put("descriptionlabel", " description:"); parametersmap.put("timestampvalue", date_format.format(new date())); parametersmap.put("erroridvalue", errorid); parametersmap.put("systemidvalue", systemid); parametersmap.put("descriptionvalue", description); freemarkerrenderer renderer = new freemarkerrenderer(); //a utility class renderer.loadtemplate(errortemplatefile); //the file exists string rendered = renderer.render(parametersmap); file temp = file.createtempfile("document", ".pdf"); file = new fileoutputstream(temp); document document = new document(); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ document.setpagesize(new rectangle(290f, 150f)); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ document.setmargins(10, 10, 10, 10); pdfwriter writer = pdfwriter.getinstance(document, file); document.open(); inputstream = new bytearrayinputstream(rendered.getbytes()); xmlworkerfontprovider provider = new xmlworkerfontprovider(); provider.register(fontfile); //the file exists fontfactory.setfontimp(provider); byte[] errorstyle = geterrorstylebytearray(); //returns byte array css file (works) xmlworkerhelper helper = xmlworkerhelper.getinstance(); helper.parsexhtml(writer, document, is, new bytearrayinputstream(errorstyle), provider); document.close(); file.close();
this code works fine, fixed height problem.
i.e. let's that:
errorid = "error-01" systemid = "system-01" description = "a short description of issue"
the produced document is:
if instead use
errorid = "error-01" systemid = "system-01" description = "a short description of issue. multiline , should stay in same pdf page."
the produced document is:
as can see, in last document have 2 pages. have 1 page changes height according content height.
is possible itext?
you can not change page size after have added content page. 1 way work around this, create document in 2 passes: first create document add content, manipulate document change page size. have been first reply if had time answer immediately.
now i've taken more time think it, i've found better solution doesn't require 2 passes. take @ htmladjustpagesize
in example, first parse content list of element
objects using method:
public elementlist parsehtml(string html, string css) throws ioexception { // css cssresolver cssresolver = new styleattrcssresolver(); cssfile cssfile = xmlworkerhelper.getcss(new bytearrayinputstream(css.getbytes())); cssresolver.addcss(cssfile); // html cssappliers cssappliers = new cssappliersimpl(fontfactory.getfontimp()); htmlpipelinecontext htmlcontext = new htmlpipelinecontext(cssappliers); htmlcontext.settagfactory(tags.gethtmltagprocessorfactory()); htmlcontext.autobookmark(false); // pipelines elementlist elements = new elementlist(); elementhandlerpipeline end = new elementhandlerpipeline(elements, null); htmlpipeline htmlpipeline = new htmlpipeline(htmlcontext, end); cssresolverpipeline csspipeline = new cssresolverpipeline(cssresolver, htmlpipeline); // xml worker xmlworker worker = new xmlworker(csspipeline, true); xmlparser p = new xmlparser(worker); p.parse(new bytearrayinputstream(html.getbytes())); return elements; }
note: i've been copy/pasting method many times decided make static method in xmlworkerhelper
class. available in next itext release.
important: have done promised, method available in xml worker release.
for testing purposes, used static string
values html , css:
public static final string html = "<table>" + "<tr><td class=\"ra\">timestamp</td><td><b>2014-11-28 11:06:09</b></td></tr>" + "<tr><td class=\"ra\">error id</td><td><b>error-01</b></td></tr>" + "<tr><td class=\"ra\">system id</td><td><b>system-01</b></td></tr>" + "<tr><td class=\"ra\">description</td><td><b>test very, long description line needs multiple lines</b></td></tr>" + "</table>"; public static final string css = "table {width: 200pt; } .ra { text-align: right; }"; public static final string dest = "results/xmlworker/html_page_size.pdf";
you can see took html looks more or less html dealing with.
i parse html , css elementlist
:
elementlist el = parsehtml(html, css);
or, starting xml worker 5.5.4:
elementlist el = xmlworkerhelper.parsetoelementlist(html, css);
so far, good. haven't told didn't know, except this: going use el
twice:
- i'll add list
columntext
in simulation mode.columntext
isn't tied document or writer yet. sole purpose this, know how space need vertically. - i'll add list
columntext
real.columntext
fit on page of size define using results obtained in simulation mode.
some code clarify mean:
// define width of 200pt float width = 200; // define height 10000pt (which more i'll ever need) float max = 10000; // create column without `writer` (strange, works) columntext ct = new columntext(null); ct.setsimplecolumn(new rectangle(width, max)); (element e : el) { ct.addelement(e); } // add content in simulation mode ct.go(true); // ask column y position float y = ct.getyline();
the above code useful 1 things: getting y
value used define page size of document
, column dimension of columntext
added real:
rectangle pagesize = new rectangle(width, max - y); // step 1 document document = new document(pagesize, 0, 0, 0, 0); // step 2 pdfwriter writer = pdfwriter.getinstance(document, new fileoutputstream(file)); // step 3 document.open(); // step 4 ct = new columntext(writer.getdirectcontent()); ct.setsimplecolumn(pagesize); (element e : el) { ct.addelement(e); } ct.go(); // step 5 document.close();
please download full htmladjustpagesize.java code , change value of html
. you'll see leads different page sizes.
Comments
Post a Comment