/*********************************************************************** * This file is part of iDempiere ERP Open Source * * http://www.idempiere.org * * * * Copyright (C) Contributors * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * * MA 02110-1301, USA. * **********************************************************************/ package org.idempiere.print.renderer; import java.awt.Color; import java.awt.Font; import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; import org.apache.ecs.MultiPartElement; import org.apache.ecs.XhtmlDocument; import org.apache.ecs.xhtml.a; import org.apache.ecs.xhtml.script; import org.apache.ecs.xhtml.span; import org.apache.ecs.xhtml.style; import org.apache.ecs.xhtml.table; import org.apache.ecs.xhtml.tbody; import org.apache.ecs.xhtml.td; import org.apache.ecs.xhtml.th; import org.apache.ecs.xhtml.thead; import org.apache.ecs.xhtml.tr; import org.compiere.model.MColumn; import org.compiere.model.MQuery; import org.compiere.model.MRole; import org.compiere.model.MStyle; import org.compiere.model.MSysConfig; import org.compiere.model.MTable; import org.compiere.model.X_AD_StyleLine; import org.compiere.print.IHTMLExtension; import org.compiere.print.MPrintColor; import org.compiere.print.MPrintFont; import org.compiere.print.MPrintFormat; import org.compiere.print.MPrintFormatItem; import org.compiere.print.MPrintTableFormat; import org.compiere.print.PrintData; import org.compiere.print.PrintDataElement; import org.compiere.print.ReportEngine; import org.compiere.print.layout.InstanceAttributeColumn; import org.compiere.print.layout.InstanceAttributeData; import org.compiere.print.layout.LayoutEngine; import org.compiere.print.layout.PrintDataEvaluatee; import org.compiere.util.CLogger; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Evaluator; import org.compiere.util.Ini; import org.compiere.util.Language; import org.compiere.util.Msg; import org.compiere.util.Util; import org.osgi.service.component.annotations.Component; import com.google.common.net.MediaType; import com.googlecode.htmlcompressor.compressor.HtmlCompressor; /** * HTML content renderer service for report engine */ @Component(service = IReportRenderer.class, immediate = true) public class HTMLReportRenderer implements IReportRenderer { private static final CLogger log = CLogger.getCLogger(HTMLReportRenderer.class); public HTMLReportRenderer() { } @Override public String getId() { return HTMLReportRendererConfiguration.ID; } @Override public String getName() { return Msg.getMsg(Env.getCtx(), "FileHTML"); } @Override public String getContentType() { return MediaType.HTML_UTF_8.toString(); } @Override public String getFileExtension() { return HTMLReportRendererConfiguration.FILE_EXTENSION; } @Override public void renderReport(ReportEngine reportEngine, HTMLReportRendererConfiguration configuration) { try { Language lang = configuration.getLanguage(); if (lang == null) lang = Language.getLoginLanguage(); Writer fw = null; if (configuration.getOutputFile() != null) fw = new OutputStreamWriter(new FileOutputStream(configuration.getOutputFile(), false), Ini.getCharset()); else fw = configuration.getOutputWriter(); createHTML (reportEngine, new BufferedWriter(fw), configuration.isOnlyTable(), lang, configuration.getExtension(), configuration.isExport()); } catch (FileNotFoundException fnfe) { log.log(Level.SEVERE, "(f) - " + fnfe.toString()); } catch (Exception e) { log.log(Level.SEVERE, "(f)", e); throw new AdempiereException(e); } } @Override public boolean isBinary() { return false; } /** * Write HTML to writer * @param reportEngine * @param writer writer * @param onlyTable if false create complete HTML document * @param language optional language - if null numbers/dates are not formatted * @param extension optional extension for html output * @param isExport when isExport = true will don't embed resource dependent zk framework */ private void createHTML (ReportEngine reportEngine, Writer writer, boolean onlyTable, Language language, IHTMLExtension extension, boolean isExport) { MPrintFormat printFormat = reportEngine.getPrintFormat(); PrintData printData = reportEngine.getPrintData(); MQuery reportEngineQuery = reportEngine.getQuery(); LayoutEngine layout = reportEngine.getLayout(); Map> mapCssInfo = new HashMap>(); try { //collect column to print List columns = new ArrayList<>(); List asiElements = new ArrayList<>(); int columnCount = 0; for (int col = 0; col < printFormat.getItemCount(); col++) { MPrintFormatItem item = printFormat.getItem(col); if (item.isPrinted()) { if (item.isTypeField() && item.isPrintInstanceAttributes()) { InstanceAttributeData asiElement = new InstanceAttributeData(item, columnCount); asiElement.readAttributesData(printData); asiElements.add(asiElement); continue; } else { columns.add(item); columnCount++; } } } if (asiElements.size() > 0) { int columnCreated = 0; for(InstanceAttributeData data : asiElements) { List instanceColumns = data.getColumns(); int index = data.getColumnIndex() + columnCreated; for(InstanceAttributeColumn c : instanceColumns) { columns.add(index, c); index++; columnCreated++; } } } String cssPrefix = extension != null ? extension.getClassPrefix() : null; if (cssPrefix != null && cssPrefix.trim().length() == 0) cssPrefix = null; table parameterTable = null; if (!printFormat.isForm()) { if (reportEngineQuery != null && reportEngineQuery.isActive()) { int rows = reportEngineQuery.getReportProcessQuery() != null ? reportEngineQuery.getReportProcessQuery().getRestrictionCount() : reportEngineQuery.getRestrictionCount(); if (rows > 0) { parameterTable = new table(); if (cssPrefix != null) parameterTable.setClass(cssPrefix + "-parameter-table"); else parameterTable.setClass("parameter-table"); parameterTable.setNeedClosingTag(false); } } } table table = new table(); if (cssPrefix != null) table.setClass(cssPrefix + "-table"); // // table.setNeedClosingTag(false); PrintWriter w = new PrintWriter(writer); XhtmlDocument doc = null; boolean minify = MSysConfig.getBooleanValue(MSysConfig.HTML_REPORT_MINIFY, true, Env.getAD_Client_ID(Env.getCtx())); if (onlyTable) w.print(compress(table.toString(), minify)); else { doc = new XhtmlDocument(); doc.getHtml().setNeedClosingTag(false); doc.getBody().setNeedClosingTag(false); doc.appendHead(""); if (extension != null && !Util.isEmpty(extension.getWebFontLinks(), true)) { doc.appendHead(extension.getWebFontLinks()); } if (extension != null && extension.getStyleURL() != null) { // maybe cache style content with key is path String pathStyleFile = extension.getFullPathStyle(); // creates a temp file - delete below Path path = Paths.get(pathStyleFile); List styleLines = Files.readAllLines(path, Ini.getCharset()); Files.delete(path); // delete temp file StringBuilder styleBuild = new StringBuilder(); for (String styleLine : styleLines){ styleBuild.append(styleLine); //.append("\n"); } appendInlineCss (doc, styleBuild); } if (extension != null && extension.getScriptURL() != null && !isExport) { script jslink = new script(); jslink.setLanguage("javascript"); jslink.setSrc(extension.getScriptURL()); doc.appendHead(jslink); } if (extension != null && !isExport){ extension.setWebAttribute(doc.getBody()); } } if (doc != null) { MPrintFormatItem item = null; int printColIndex = -1; for(int col = 0; col < columns.size(); col++) { Object colobj = columns.get(col); if (colobj instanceof MPrintFormatItem) item = (MPrintFormatItem) colobj; else if (colobj instanceof InstanceAttributeColumn) item = ((InstanceAttributeColumn) colobj).getPrintFormatItem(); if(item != null) { printColIndex++; addCssInfo(printFormat, item, printColIndex, mapCssInfo); } }//IDEMPIERE-4113 appendInlineCss(doc, mapCssInfo); StringBuilder styleBuild = new StringBuilder(); MPrintTableFormat tf = printFormat.getTableFormat(); CSSInfo cssInfo = new CSSInfo(tf.getPageHeader_Font(), tf.getPageHeaderFG_Color()); if (cssPrefix != null) { if (parameterTable != null) styleBuild.append("."+cssPrefix + "-parameter-table th").append(cssInfo.getCssRule()); styleBuild.append("."+cssPrefix + "-table th").append(cssInfo.getCssRule()); } else { if (parameterTable != null) styleBuild.append("parameter-table th").append(cssInfo.getCssRule()); styleBuild.append("table th").append(cssInfo.getCssRule()); } cssInfo = new CSSInfo(tf.getParameter_Font(), tf.getParameter_Color()); styleBuild.append(".tr-parameter td").append(cssInfo.getCssRule()); cssInfo = new CSSInfo(tf.getFunct_Font(), tf.getFunctFG_Color()); styleBuild.append(".tr-function td").append(cssInfo.getCssRule()); MPrintFont printFont = MPrintFont.get(printFormat.getAD_PrintFont_ID()); Font base = printFont.getFont(); Font newFont = new Font(base.getName(), Font.PLAIN, base.getSize()-1); cssInfo = new CSSInfo(newFont, null); styleBuild.append(".tr-level-1 td").append(cssInfo.getCssRule()); newFont = new Font(base.getName(), Font.PLAIN, base.getSize()-2); cssInfo = new CSSInfo(newFont, null); styleBuild.append(".tr-level-2 td").append(cssInfo.getCssRule()); styleBuild = new StringBuilder(styleBuild.toString().replaceAll(";", "!important;")); appendInlineCss (doc, styleBuild); w.print(compress(doc.toString(), minify)); w.print("
"); String paraWrapId = null; if (parameterTable != null) { paraWrapId = cssPrefix + "-para-table-wrap"; w.print("
"); w.print(""+Msg.getMsg(Env.getCtx(), "Parameter")+""); w.print(compress(parameterTable.toString(), minify)); tr tr = new tr(); tr.setClass("tr-parameter"); MQuery query = reportEngineQuery; if (reportEngineQuery.getReportProcessQuery() != null) query = reportEngineQuery.getReportProcessQuery(); for (int r = 0; r < query.getRestrictionCount(); r++) { if (r > 0) { tr = new tr(); tr.setClass("tr-parameter"); } td td = new td(); tr.addElement(td); td.addElement(query.getInfoName(r)); td = new td(); tr.addElement(td); td.addElement(query.getInfoOperator(r)); td = new td(); tr.addElement(td); td.addElement(query.getInfoDisplayAll(r)); w.print(compress(tr.toString(), minify)); } w.print(""); w.print("
"); } StringBuilder tableWrapDiv = new StringBuilder(); tableWrapDiv.append("
"); w.print(compress(tableWrapDiv.toString(), minify)); w.print(compress(table.toString(), minify)); } thead thead = new thead(); tbody tbody = new tbody(); tbody.setNeedClosingTag(false); Boolean [] colSuppressRepeats = layout == null || layout.colSuppressRepeats == null? LayoutEngine.getColSuppressRepeats(printFormat):layout.colSuppressRepeats; Object [] preValues = null; if (colSuppressRepeats != null){ preValues = new Object [colSuppressRepeats.length]; } int printColIndex = -1; HashMap suppressMap = new HashMap<>(); // for all rows (-1 = header row) for (int row = -1; row < printData.getRowCount(); row++) { tr tr = new tr(); if (row != -1) { printData.setRowIndex(row); if (extension != null && !isExport) { extension.extendRowElement(tr, printData); } if (printData.isFunctionRow()) { tr.setClass(cssPrefix + "-functionrow"); } else if ( row < printData.getRowCount() && printData.isFunctionRow(row+1)) { tr.setClass(cssPrefix + "-lastgrouprow"); } // add row to table body //tbody.addElement(tr); } else { // add row to table header thead.addElement(tr); } printColIndex = -1; // for all columns for (int col = 0; col < columns.size(); col++) { Object colObj = columns.get(col); MPrintFormatItem item = null; InstanceAttributeColumn instanceAttributeColumn = null; if (colObj instanceof MPrintFormatItem) { item = (MPrintFormatItem) colObj; } else if (colObj instanceof InstanceAttributeColumn) { instanceAttributeColumn = (InstanceAttributeColumn) colObj; item = instanceAttributeColumn.getPrintFormatItem(); } if (item != null) { printColIndex++; // header row if (row == -1) { th th = new th(); tr.addElement(th); String columnHeader = instanceAttributeColumn != null ? instanceAttributeColumn.getName() : item.getPrintName(language); th.addElement(Util.maskHTML(columnHeader)); if (cssPrefix != null && instanceAttributeColumn == null) { MColumn column = MColumn.get(Env.getCtx(), item.getAD_Column_ID()); if (column != null && column.getAD_Column_ID() > 0) { if (DisplayType.isNumeric(column.getAD_Reference_ID())) { th.setClass(cssPrefix + "-number"); } } } if (item.isSuppressNull()) { suppressMap.put(printColIndex, th); th.setID("report-th-"+printColIndex); } } else { td td = new td(); tr.addElement(td); MStyle style = item.getAD_FieldStyle_ID() > 0 ? MStyle.get(Env.getCtx(), item.getAD_FieldStyle_ID()) : null; Object obj = instanceAttributeColumn != null ? instanceAttributeColumn.getPrintDataElement(row) : printData.getNodeByPrintFormatItemId(item.getAD_PrintFormatItem_ID()); if (obj == null || !ReportEngine.isDisplayPFItem(printData, item)){ td.addElement(" "); if (colSuppressRepeats != null && colSuppressRepeats[printColIndex]){ preValues[printColIndex] = null; } if (item.isSuppressNull() && obj != null && suppressMap.containsKey(printColIndex)) suppressMap.remove(printColIndex); } else if (obj instanceof PrintDataElement) { PrintDataElement pde = (PrintDataElement) obj; String value = pde.getValueDisplay(language); // formatted if (colSuppressRepeats != null && colSuppressRepeats[printColIndex]){ if (value.equals(preValues[printColIndex])){ td.addElement(" "); continue; }else{ preValues[printColIndex] = value; } } if (item.isSuppressNull() && obj != null && suppressMap.containsKey(printColIndex)) suppressMap.remove(printColIndex); if (pde.getColumnName().endsWith("_ID") && extension != null && !isExport) { boolean isZoom = false; if (item.getColumnName().equals("Record_ID")) { Object tablePDE = printData.getNode("AD_Table_ID"); if (tablePDE != null && tablePDE instanceof PrintDataElement) { int tableID = -1; try { tableID = Integer.parseInt(((PrintDataElement)tablePDE).getValueAsString()); } catch (Exception e) { tableID = -1; } if (tableID > 0) { MTable mTable = MTable.get(Env.getCtx(), tableID); String tableName = mTable.getTableName(); value = reportEngine.getIdentifier(mTable, tableName, Integer.parseInt(value)); String foreignColumnName = tableName + "_ID"; pde.setForeignColumnName(foreignColumnName); isZoom = true; } } } else { isZoom = true; } if (isZoom) { // check permission on the zoomed window MTable mTable = MTable.get(Env.getCtx(), pde.getForeignColumnName().substring(0, pde.getForeignColumnName().length()-3)); int Record_ID = -1; try { Record_ID = Integer.parseInt(pde.getValueAsString()); } catch (Exception e) { Record_ID = -1; } Boolean canAccess = null; if (Record_ID >= 0 && mTable != null) { int AD_Window_ID = Env.getZoomWindowID(mTable.get_ID(), Record_ID); canAccess = MRole.getDefault().getWindowAccess(AD_Window_ID); } if (canAccess == null) { isZoom = false; } } if (isZoom) { //link for column a href = new a("javascript:void(0)"); href.setID(pde.getColumnName() + "_" + row + "_a"); td.addElement(href); href.addElement(Util.maskHTML(value)); if (cssPrefix != null) href.setClass(cssPrefix + "-href"); // Set Style if(style != null && style.isWrapWithSpan()) setStyle(printData, href, style); else setStyle(printData, td, style); extension.extendIDColumn(row, td, href, pde); } else { // Set Style if(style != null && style.isWrapWithSpan()) { span span = new span(); setStyle(printData, span, style); span.addElement(Util.maskHTML(value)); td.addElement(span); } else { setStyle(printData, td, style); td.addElement(Util.maskHTML(value)); } } } else { // Set Style if(style != null && style.isWrapWithSpan()) { span span = new span(); setStyle(printData, span, style); span.addElement(Util.maskHTML(value)); td.addElement(span); } else { setStyle(printData, td, style); td.addElement(Util.maskHTML(value)); } } if (cssPrefix != null) { if (DisplayType.isNumeric(pde.getDisplayType())) td.setClass(cssPrefix + "-number"); else if (DisplayType.isDate(pde.getDisplayType())) td.setClass(cssPrefix + "-date"); else td.setClass(cssPrefix + "-text"); } } else if (obj instanceof PrintData) { // ignore contained Data } else log.log(Level.SEVERE, "Element not PrintData(Element) " + obj.getClass()); } } // printed } // for all columns /* output table header */ if (row == -1){ w.print(compress(thead.toString(), minify)); // output open of tbody w.print(compress(tbody.toString(), minify)); }else{ // output row by row w.print(compress(tr.toString(), minify)); } } // for all rows w.print(""); w.print(""); if (suppressMap.size() > 0) { StringBuilder st = new StringBuilder(); for(th t : suppressMap.values()) { if (st.length() > 0) st.append(","); st.append("#").append(t.getAttribute("id")); } st.append(" {\n\t\tdisplay:none;\n\t}"); style styleTag = new style(); styleTag.addElement(st.toString()); w.print(compress(styleTag.toString(), minify)); } if (!onlyTable) { w.print("
"); w.print("
"); w.print(""); w.print(""); } w.flush(); w.close(); } catch (Exception e) { log.log(Level.SEVERE, "(w)", e); throw new AdempiereException(e); } } // createHTML /** * Compress html content * @param src * @param minify * @return compressed content */ public static String compress(String src, boolean minify) { if(minify) { HtmlCompressor compressor = new HtmlCompressor(); compressor.setEnabled(true); compressor.setCompressCss(true); compressor.setCompressJavaScript(true); compressor.setRemoveComments(true); compressor.setRemoveMultiSpaces(true); compressor.setRemoveIntertagSpaces(true); // compressor.setGenerateStatistics(false); // compressor.setRemoveQuotes(false); // compressor.setSimpleDoctype(false); // compressor.setRemoveScriptAttributes(false); // compressor.setRemoveStyleAttributes(false); // compressor.setRemoveLinkAttributes(false); // compressor.setRemoveFormAttributes(false); // compressor.setRemoveInputAttributes(false); // compressor.setSimpleBooleanAttributes(false); // compressor.setRemoveJavaScriptProtocol(false); // compressor.setRemoveHttpProtocol(false); // compressor.setRemoveHttpsProtocol(false); // compressor.setPreserveLineBreaks(false); return compressor.compress(src); } else { return src; } } /** * Append css for table from mapCssInfo * @param doc */ public static void appendInlineCss (XhtmlDocument doc, Map> mapCssInfo){ StringBuilder buildCssInline = new StringBuilder(); // each entry is a css class for (Entry> cssClassInfo : mapCssInfo.entrySet()){ // each column is a css name. for (int i = 0; i < cssClassInfo.getValue().size(); i++){ if (i > 0) buildCssInline.append (","); buildCssInline.append(cssClassInfo.getValue().get(i).getCssSelector()); } buildCssInline.append(cssClassInfo.getKey().getCssRule()); buildCssInline.append("\n"); } appendInlineCss (doc, buildCssInline); } /** * Append inline css content * @param doc * @param buildCssInline */ public static void appendInlineCss (XhtmlDocument doc, StringBuilder buildCssInline){ if (buildCssInline.length() > 0){ buildCssInline.insert(0, ""); doc.appendHead(buildCssInline.toString()); } } /** * Create css info from formatItem, add all column has same CSSInfo in a list * @param formatItem * @param index */ public static void addCssInfo (MPrintFormat printFormat, MPrintFormatItem formatItem, int index, Map> mapCssInfo){ CSSInfo cadidateCss = new CSSInfo(printFormat, formatItem); if (mapCssInfo.containsKey(cadidateCss)) { mapCssInfo.get(cadidateCss).add(new ColumnInfo(index, formatItem)); } else { List newColumnList = new ArrayList(); newColumnList.add(new ColumnInfo(index, formatItem)); mapCssInfo.put(cadidateCss, newColumnList); } } /** * Store info for css rule * @author hieplq */ public static class CSSInfo { private Font font; private Color color; private String cssStr; public CSSInfo (MPrintFormat printFormat, MPrintFormatItem item){ MPrintFont mPrintFont = null; if (item.getAD_PrintFont_ID() > 0) { mPrintFont = MPrintFont.get(item.getAD_PrintFont_ID()); } else if (printFormat.getAD_PrintFont_ID() > 0) { mPrintFont = MPrintFont.get(printFormat.getAD_PrintFont_ID()); } if (mPrintFont != null && mPrintFont.getAD_PrintFont_ID() > 0) { font = mPrintFont.getFont(); } MPrintColor mPrintColor = null; if (item.getAD_PrintColor_ID() > 0) { mPrintColor = MPrintColor.get(Env.getCtx(), item.getAD_PrintColor_ID()); } else if (printFormat.getAD_PrintColor_ID() > 0) { mPrintColor = MPrintColor.get(Env.getCtx(), printFormat.getAD_PrintColor_ID()); } if (mPrintColor != null && mPrintColor.getAD_PrintColor_ID() > 0) { color = mPrintColor.getColor(); } } public CSSInfo (Font font, Color color) { this.font = font; this.color = color; } /** * Sum hashCode of color and font */ @Override public int hashCode() { return (color == null ? 0 : color.hashCode()) + (font == null ? 0 : font.hashCode()); } /** * equal when same color and font */ @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof CSSInfo) || obj.hashCode() != this.hashCode()) return false; CSSInfo compareObj = (CSSInfo)obj; return compareObj (compareObj.color, color) && compareObj (compareObj.font, font); } /** * Compare two object equal when both is null or equal * @param obj1 * @param obj2 * @return true if both is null or equal */ protected boolean compareObj(Object obj1, Object obj2) { if (obj1 == null && obj2 != null) return false; if (obj1 == null && obj2 == null){ return true; } return obj1.equals(obj2); } /** * Append a css rule to a css class * @param cssBuild css class builder * @param ruleName * @param ruleValue */ protected void addCssRule(StringBuilder cssBuild, String ruleName, String ruleValue) { cssBuild.append (ruleName); cssBuild.append (":"); cssBuild.append (ruleValue); cssBuild.append (";"); } /** * Build css rule * @return css rule */ public String getCssRule (){ if (cssStr != null) return cssStr; StringBuilder cssBuild = new StringBuilder(); cssBuild.append ("{"); if (font != null){ String fontFamily = font.getFamily(); fontFamily = getCSSFontFamily(fontFamily); if (fontFamily != null){ addCssRule(cssBuild, "font-family", fontFamily); } if (font.isBold()) { addCssRule(cssBuild, "font-weight", "bold"); } if (font.isItalic()) { addCssRule(cssBuild, "font-style", "italic"); } int size = font.getSize(); addCssRule(cssBuild, "font-size", size + "pt"); } if (color != null) { cssBuild.append("color:rgb("); cssBuild.append(color.getRed()); cssBuild.append(","); cssBuild.append(color.getGreen()); cssBuild.append(","); cssBuild.append(color.getBlue()); cssBuild.append(");"); } cssBuild.append ("}"); cssStr = cssBuild.toString(); return cssStr; } } /** * Get CSS font family * @param fontFamily Java font family * @return CSS font family */ private static String getCSSFontFamily(String fontFamily) { if ("Dialog".equals(fontFamily) || "DialogInput".equals(fontFamily) || "Monospaced".equals(fontFamily)) { return "monospace"; } else if ("SansSerif".equals(fontFamily)) { return "sans-serif"; } else if ("Serif".equals(fontFamily)) { return "serif"; } return null; } /** * Set inline style of element * @param printData * @param element * @param style */ public static void setStyle(PrintData printData, MultiPartElement element, MStyle style) { if (style == null || style.getAD_Style_ID() == 0) return; X_AD_StyleLine[] lines = style.getStyleLines(); StringBuilder styleBuilder = new StringBuilder(); for (X_AD_StyleLine line : lines) { String inlineStyle = line.getInlineStyle().trim(); String displayLogic = line.getDisplayLogic(); if (!Util.isEmpty(displayLogic)) { if (!Evaluator.evaluateLogic(new PrintDataEvaluatee(null, printData), displayLogic)) continue; } if (styleBuilder.length() > 0 && !(styleBuilder.charAt(styleBuilder.length()-1)==';')) styleBuilder.append("; "); styleBuilder.append(inlineStyle); } if(styleBuilder.length() > 0) element.setStyle(styleBuilder.toString()); // } /** * Store info of report column,
* now just use index to create css selector, but for later maybe will construct a complex class name * @author hieplq * */ public static class ColumnInfo { protected static String CSS_SELECTOR_TEMPLATE = "table > tbody > tr > td:nth-child(%1$s)"; int index = -1; public ColumnInfo (int index, MPrintFormatItem formatItem){ this.index = index; } public String getCssSelector(){ return String.format(CSS_SELECTOR_TEMPLATE, index + 1); } } @Override public Class getConfigurationType() { return HTMLReportRendererConfiguration.class; } }