001/* 002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Thierry Delprat 018 */ 019package org.nuxeo.template.processors.jxls; 020 021import java.io.BufferedInputStream; 022import java.io.BufferedOutputStream; 023import java.io.File; 024import java.io.FileInputStream; 025import java.io.FileOutputStream; 026import java.io.IOException; 027import java.io.InputStream; 028import java.io.OutputStream; 029import java.util.ArrayList; 030import java.util.List; 031import java.util.Map; 032 033import net.sf.jxls.exception.ParsePropertyException; 034import net.sf.jxls.transformer.XLSTransformer; 035 036import org.apache.poi.openxml4j.exceptions.InvalidFormatException; 037import org.jxls.common.Context; 038import org.jxls.util.JxlsHelper; 039import org.nuxeo.common.utils.FileUtils; 040import org.nuxeo.ecm.core.api.Blob; 041import org.nuxeo.ecm.core.api.Blobs; 042import org.nuxeo.ecm.core.api.DocumentModel; 043import org.nuxeo.ecm.core.api.NuxeoException; 044import org.nuxeo.ecm.platform.mimetype.interfaces.MimetypeRegistry; 045import org.nuxeo.runtime.api.Framework; 046import org.nuxeo.runtime.services.config.ConfigurationService; 047import org.nuxeo.template.api.TemplateInput; 048import org.nuxeo.template.api.TemplateProcessor; 049import org.nuxeo.template.api.adapters.TemplateBasedDocument; 050import org.nuxeo.template.context.SimpleContextBuilder; 051import org.nuxeo.template.processors.AbstractTemplateProcessor; 052 053/** 054 * JXLS {@link TemplateProcessor} 055 * 056 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a> 057 */ 058public class JXLSTemplateProcessor extends AbstractTemplateProcessor { 059 060 public static final String TEMPLATE_TYPE = "JXLS"; 061 062 /** 063 * Configuration property to use the old JXLS 1 instead of JXLS 2. 064 * 065 * @since 11.1 066 */ 067 public static final String USE_JXLS1_CONFIG_PROP = "org.nuxeo.template.rendering.jxls1"; 068 069 protected SimpleContextBuilder contextBuilder = new SimpleContextBuilder(); 070 071 protected boolean useJXLS1() { 072 return Framework.getService(ConfigurationService.class).isBooleanTrue(USE_JXLS1_CONFIG_PROP); 073 } 074 075 @Override 076 public Blob renderTemplate(TemplateBasedDocument templateBasedDocument, String templateName) throws IOException { 077 078 Blob sourceTemplateBlob = getSourceTemplateBlob(templateBasedDocument, templateName); 079 List<TemplateInput> params = templateBasedDocument.getParams(templateName); 080 081 DocumentModel doc = templateBasedDocument.getAdaptedDoc(); 082 Map<String, Object> ctx = contextBuilder.build(doc, templateName); 083 084 JXLSBindingResolver resolver = new JXLSBindingResolver(); 085 086 resolver.resolve(params, ctx, templateBasedDocument); 087 088 File workingDir = getWorkingDir(); 089 File generated = new File(workingDir, "JXLSresult-" + System.currentTimeMillis()); 090 generated.createNewFile(); 091 092 File input = new File(workingDir, "JXLSInput-" + System.currentTimeMillis()); 093 input.createNewFile(); 094 095 sourceTemplateBlob.transferTo(input); 096 097 if (useJXLS1()) { 098 XLSTransformer transformer = new XLSTransformer(); 099 configureTransformer(transformer); 100 try { 101 transformer.transformXLS(input.getAbsolutePath(), ctx, generated.getAbsolutePath()); 102 } catch (InvalidFormatException | ParsePropertyException e) { 103 throw new NuxeoException(e); 104 } 105 } else { 106 try (InputStream is = new BufferedInputStream(new FileInputStream(input)); 107 OutputStream os = new BufferedOutputStream(new FileOutputStream(generated))) { 108 JxlsHelper.getInstance().processTemplate(is, os, new Context(ctx)); 109 } catch (IllegalStateException | IOException e) { 110 throw new NuxeoException(e); 111 } 112 } 113 114 input.delete(); 115 116 Blob newBlob = Blobs.createBlob(generated); 117 118 String templateFileName = sourceTemplateBlob.getFilename(); 119 120 // set the output file name 121 String targetFileExt = FileUtils.getFileExtension(templateFileName); 122 String targetFileName = FileUtils.getFileNameNoExt(templateBasedDocument.getAdaptedDoc().getTitle()); 123 targetFileName = targetFileName + "." + targetFileExt; 124 newBlob.setFilename(targetFileName); 125 MimetypeRegistry mimetypeRegistry = Framework.getService(MimetypeRegistry.class); 126 newBlob.setMimeType(mimetypeRegistry.getMimetypeFromExtension(targetFileExt)); 127 128 // mark the file for automatic deletion on GC 129 Framework.trackFile(generated, newBlob); 130 return newBlob; 131 132 } 133 134 protected void configureTransformer(XLSTransformer transformer) { 135 // NOP but subclass may use this to register a CellProcessor or a 136 // RowProcessor 137 } 138 139 @Override 140 public List<TemplateInput> getInitialParametersDefinition(Blob blob) { 141 return new ArrayList<>(); 142 } 143 144}