dataview - excel export
This commit is contained in:
parent
303448d766
commit
6cfea74397
5 changed files with 593 additions and 77 deletions
|
|
@ -23,22 +23,30 @@
|
|||
*******************************************************************************/
|
||||
package org.imixs.workflow.office.dataview;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.imixs.archive.core.SnapshotService;
|
||||
import org.imixs.workflow.FileData;
|
||||
import org.imixs.workflow.ItemCollection;
|
||||
import org.imixs.workflow.engine.DocumentService;
|
||||
import org.imixs.workflow.engine.WorkflowService;
|
||||
import org.imixs.workflow.exceptions.ModelException;
|
||||
import org.imixs.workflow.exceptions.PluginException;
|
||||
import org.imixs.workflow.exceptions.QueryException;
|
||||
import org.imixs.workflow.faces.data.ViewController;
|
||||
import org.imixs.workflow.faces.data.ViewHandler;
|
||||
import org.imixs.workflow.office.forms.CustomFormController;
|
||||
import org.imixs.workflow.office.forms.CustomFormSection;
|
||||
|
||||
import com.alexanderlogistics.mahnlauf.InkassoExportAdapter;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.enterprise.context.Conversation;
|
||||
import jakarta.enterprise.context.ConversationScoped;
|
||||
|
|
@ -69,6 +77,10 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||
public class DataViewController extends ViewController {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String ERROR_CONFIG = "CONFIG_ERROR";
|
||||
public static final int MAX_ROWS = 3000;
|
||||
|
||||
private List<CustomFormSection> sections = null;
|
||||
private List<ItemCollection> viewItemDefinitions = null;
|
||||
protected ItemCollection dataDefinition = null;
|
||||
|
|
@ -85,6 +97,12 @@ public class DataViewController extends ViewController {
|
|||
@Inject
|
||||
private DocumentService documentService;
|
||||
|
||||
@Inject
|
||||
private WorkflowService workflowService;
|
||||
|
||||
@Inject
|
||||
SnapshotService snapshotService;
|
||||
|
||||
@Inject
|
||||
CustomFormController customFormController;
|
||||
|
||||
|
|
@ -111,9 +129,7 @@ public class DataViewController extends ViewController {
|
|||
* This method loads the custom form sections
|
||||
*/
|
||||
public void onLoad() {
|
||||
|
||||
String cacheid = null;
|
||||
logger.info("> onload...");
|
||||
|
||||
// Important: start a new conversation beause of the usage of the
|
||||
// CustomFormController!
|
||||
|
|
@ -134,7 +150,7 @@ public class DataViewController extends ViewController {
|
|||
dataDefinition = documentService.load(uniqueid);
|
||||
}
|
||||
|
||||
logger.info("> cacheid=" + cacheid);
|
||||
logger.finest("> cacheid=" + cacheid);
|
||||
if (cacheid != null && !cacheid.isEmpty()) {
|
||||
filter = dataViewCache.get(cacheid);
|
||||
} else {
|
||||
|
|
@ -145,13 +161,21 @@ public class DataViewController extends ViewController {
|
|||
// Init new Filter....
|
||||
if (dataDefinition != null) {
|
||||
filter.setItemValue("txtWorkflowEditorCustomForm", dataDefinition.getItemValue("form"));
|
||||
filter.setItemValue("name", dataDefinition.getItemValueString("name"));
|
||||
filter.setItemValue("description", dataDefinition.getItemValueString("description"));
|
||||
viewItemDefinitions = DataViewDefinitionController
|
||||
.computeDataViewItemDefinitions(dataDefinition);
|
||||
|
||||
customFormController.computeFieldDefinition(filter);
|
||||
sections = customFormController.getSections();
|
||||
|
||||
logger.info(" < cached page index=" + filter.getItemValueInteger("pageIndex"));
|
||||
// Update View Handler settings
|
||||
String sortBy = dataDefinition.getItemValueString("sort.by");
|
||||
if (sortBy.isEmpty()) {
|
||||
sortBy = "$modified";
|
||||
}
|
||||
this.setSortBy(sortBy);
|
||||
this.setSortReverse(dataDefinition.getItemValueBoolean("sort.reverse"));
|
||||
this.setPageIndex(filter.getItemValueInteger("pageIndex"));
|
||||
if (!filter.getItemValueString("query").isEmpty()) {
|
||||
query = filter.getItemValueString("query");
|
||||
|
|
@ -229,7 +253,7 @@ public class DataViewController extends ViewController {
|
|||
// Replace all occurrences in the query case-insensitive.
|
||||
query = query.replaceAll("(?i)\\{" + Pattern.quote(itemName) + "\\}", itemValue);
|
||||
}
|
||||
logger.info("query=" + query);
|
||||
logger.finest("query=" + query);
|
||||
filter.setItemValue("query", query);
|
||||
|
||||
// Prefetch data to update total count and page count
|
||||
|
|
@ -246,29 +270,6 @@ public class DataViewController extends ViewController {
|
|||
return query;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns the current workItem. If no workitem is defined the method
|
||||
// * Instantiates a empty ItemCollection.
|
||||
// *
|
||||
// * @return - current workItem or null if not set
|
||||
// */
|
||||
// public ItemCollection getData() {
|
||||
// // do initialize an empty workItem here if null
|
||||
// if (data == null) {
|
||||
// reset();
|
||||
// }
|
||||
// return data;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Set the current workItem
|
||||
// *
|
||||
// * @param workitem - new reference or null to clear the current workItem.
|
||||
// */
|
||||
// public void setData(ItemCollection document) {
|
||||
// this.data = document;
|
||||
// }
|
||||
|
||||
/**
|
||||
* This method navigates back in the page index and caches the current page
|
||||
* index
|
||||
|
|
@ -285,7 +286,6 @@ public class DataViewController extends ViewController {
|
|||
public void forward() {
|
||||
viewHandler.forward(this);
|
||||
filter.setItemValue("pageIndex", this.getPageIndex());
|
||||
logger.info("-> forward to page " + this.getPageIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -297,9 +297,97 @@ public class DataViewController extends ViewController {
|
|||
((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest())
|
||||
.getSession().getMaxInactiveInterval() * 1000);
|
||||
conversation.begin();
|
||||
logger.log(Level.INFO, "......start new conversation, id={0}",
|
||||
logger.log(Level.FINEST, "......start new conversation, id={0}",
|
||||
conversation.getId());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports data into a excel template processed by apache-poi
|
||||
*
|
||||
* @throws PluginException
|
||||
* @throws QueryException
|
||||
*/
|
||||
public String export() throws PluginException, QueryException {
|
||||
|
||||
// build query and prepare dataset
|
||||
run();
|
||||
|
||||
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
|
||||
String targetFileName = dataDefinition.getItemValueString("poi.targetFilename");
|
||||
if (targetFileName.isEmpty()) {
|
||||
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
||||
"Missing Excel Export definition - check configuration!");
|
||||
}
|
||||
logger.info("start export : " + targetFileName + "...");
|
||||
logger.fine(query);
|
||||
|
||||
// load template
|
||||
FileData fileData = loadTemplate();
|
||||
|
||||
if (fileData == null) {
|
||||
// we did not found the template!
|
||||
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
||||
"Missing Excel Export Template - check DataView definition!");
|
||||
}
|
||||
targetFileName = targetFileName + "_" + dateformat.format(new Date()) + ".xlsx";
|
||||
try {
|
||||
// test if query exceeds max count
|
||||
int totalCount = documentService.count(query);
|
||||
if (totalCount > MAX_ROWS) {
|
||||
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
||||
"Data can not be exported into Excel because dataset exceeds " + MAX_ROWS + " rows!");
|
||||
}
|
||||
String sortBy = dataDefinition.getItemValueString("sort.by");
|
||||
if (sortBy.isEmpty()) {
|
||||
sortBy = "$modified"; // default
|
||||
}
|
||||
List<ItemCollection> invoices = documentService.find(query, MAX_ROWS, 0, sortBy,
|
||||
dataDefinition.getItemValueBoolean("sort.reverse"));
|
||||
if (invoices.size() > 0) {
|
||||
String referenceCell = dataDefinition.getItemValueString("poi.referenceCell");
|
||||
DataViewPOIHelper.insertDataRows(invoices, referenceCell, viewItemDefinitions, fileData);
|
||||
}
|
||||
|
||||
// create a temp event
|
||||
ItemCollection event = new ItemCollection().setItemValue("txtActivityResult",
|
||||
dataDefinition.getItemValue("poi.update"));
|
||||
ItemCollection poiConfig = workflowService.evalWorkflowResult(event, "poi-update", dataDefinition,
|
||||
false);
|
||||
DataViewPOIHelper.poiUpdate(filter, fileData, poiConfig, workflowService);
|
||||
|
||||
fileData.setName(targetFileName);
|
||||
|
||||
// See:
|
||||
// https://stackoverflow.com/questions/9391838/how-to-provide-a-file-download-from-a-jsf-backing-bean
|
||||
DataViewPOIHelper.downloadExcelFile(fileData);
|
||||
} catch (IOException | QueryException e) {
|
||||
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
||||
"Failed to generate Excel Export: " + e.getMessage());
|
||||
}
|
||||
|
||||
// return "/pages/admin/excel_export_rechnungsausgang.jsf?faces-redirect=true";
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the first excel poi template from the Data Definition
|
||||
*
|
||||
* @param name in attribute txtname
|
||||
*
|
||||
*
|
||||
*/
|
||||
private FileData loadTemplate() {
|
||||
|
||||
// first filename
|
||||
List<FileData> fileDataList = dataDefinition.getFileData();
|
||||
if (fileDataList != null && fileDataList.size() > 0) {
|
||||
String fileName = fileDataList.get(0).getName();
|
||||
return snapshotService.getWorkItemFile(dataDefinition.getUniqueID(), fileName);
|
||||
}
|
||||
// no file data available!
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,356 @@
|
|||
/*******************************************************************************
|
||||
* Imixs Workflow Technology
|
||||
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
||||
* http://www.imixs.com
|
||||
*
|
||||
* 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 can receive a copy of the GNU General Public
|
||||
* License at http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* Contributors:
|
||||
* Imixs Software Solutions GmbH - initial API and implementation
|
||||
* Ralph Soika
|
||||
*
|
||||
*******************************************************************************/
|
||||
package org.imixs.workflow.office.dataview;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.poi.ss.usermodel.CellCopyPolicy;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
||||
import org.apache.poi.ss.usermodel.Name;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.imixs.workflow.FileData;
|
||||
import org.imixs.workflow.ItemCollection;
|
||||
import org.imixs.workflow.engine.WorkflowService;
|
||||
import org.imixs.workflow.exceptions.PluginException;
|
||||
import org.imixs.workflow.util.XMLParser;
|
||||
|
||||
import jakarta.faces.context.ExternalContext;
|
||||
import jakarta.faces.context.FacesContext;
|
||||
|
||||
/**
|
||||
* The DataViewPOIHelper provides methods to update a excel template with the
|
||||
* help of the Apache POI framework.
|
||||
*
|
||||
*
|
||||
* @author rsoika
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class DataViewPOIHelper {
|
||||
private static Logger logger = Logger.getLogger(DataViewPOIHelper.class.getName());
|
||||
public static final String ERROR_CONFIG = "CONFIG_ERROR";
|
||||
|
||||
/**
|
||||
* Helper method to initialize a file download
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void downloadExcelFile(FileData fileData) throws IOException {
|
||||
|
||||
FacesContext facesContext = FacesContext.getCurrentInstance();
|
||||
ExternalContext externalContext = facesContext.getExternalContext();
|
||||
|
||||
externalContext.responseReset();
|
||||
externalContext.setResponseContentType("application/vnd.ms-excel");
|
||||
externalContext.setResponseContentLength(fileData.getContent().length);
|
||||
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileData.getName() + "\"");
|
||||
|
||||
OutputStream output = externalContext.getResponseOutputStream();
|
||||
|
||||
// Now you can write the InputStream of the file to the above OutputStream the
|
||||
// usual way.
|
||||
output.write(fileData.getContent());
|
||||
|
||||
facesContext.responseComplete(); // Important! Otherwise Faces will attempt to render the response which
|
||||
// obviously will fail since it's already written with a file and closed.
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper method inserts a row for each invoice
|
||||
*
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static void insertDataRows(List<ItemCollection> dataset, String referenceCell,
|
||||
List<ItemCollection> viewItemDefinitions,
|
||||
FileData fileData) throws PluginException {
|
||||
// load XSSFWorkbook
|
||||
try (InputStream imputStream = new ByteArrayInputStream(fileData.getContent())) {
|
||||
XSSFWorkbook doc = new XSSFWorkbook(imputStream);
|
||||
// NOTE: we only take the first sheet !
|
||||
XSSFSheet sheet = doc.getSheetAt(0);
|
||||
|
||||
CellReference cr = new CellReference(referenceCell);
|
||||
XSSFRow referenceRow = sheet.getRow(cr.getRow());
|
||||
int referenceRowPos = referenceRow.getRowNum() + 1;
|
||||
int rowPos = referenceRowPos;
|
||||
// int lastRow = sheet.getLastRowNum();
|
||||
int lastRow = 999;
|
||||
logger.finest("Last rownum=" + lastRow);
|
||||
sheet.shiftRows(rowPos, lastRow, dataset.size(), true, true);
|
||||
|
||||
for (ItemCollection workitem : dataset) {
|
||||
logger.finest("......copy row...");
|
||||
|
||||
// now create a new line..
|
||||
XSSFRow row = sheet.createRow(rowPos);
|
||||
row.copyRowFrom(referenceRow, new CellCopyPolicy());
|
||||
// insert values
|
||||
int cellNum = 0;
|
||||
for (ItemCollection itemDef : viewItemDefinitions) {
|
||||
String type = itemDef.getItemValueString("item.type");
|
||||
String name = itemDef.getItemValueString("item.name");
|
||||
switch (type) {
|
||||
case "xs:double":
|
||||
row.getCell(cellNum).setCellValue(workitem.getItemValueDouble(name));
|
||||
break;
|
||||
case "xs:float":
|
||||
row.getCell(cellNum).setCellValue(workitem.getItemValueFloat(name));
|
||||
break;
|
||||
case "xs:int":
|
||||
row.getCell(cellNum).setCellValue(workitem.getItemValueInteger(name));
|
||||
break;
|
||||
case "xs:date":
|
||||
row.getCell(cellNum).setCellValue(workitem.getItemValueDate(name));
|
||||
break;
|
||||
|
||||
default:
|
||||
row.getCell(cellNum).setCellValue(workitem.getItemValueString(name));
|
||||
}
|
||||
cellNum++;
|
||||
}
|
||||
|
||||
rowPos++;
|
||||
}
|
||||
// delete reference row
|
||||
sheet.shiftRows(referenceRowPos, lastRow + dataset.size(), -1, true, true);
|
||||
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
// write back the file
|
||||
doc.write(byteArrayOutputStream);
|
||||
doc.close();
|
||||
byte[] newContent = byteArrayOutputStream.toByteArray();
|
||||
fileData.setContent(newContent);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new PluginException(DataViewPOIHelper.class.getSimpleName(), ERROR_CONFIG,
|
||||
"failed to update excel export: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper method applies the POI update defintiions a row for each invoice
|
||||
*
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static void poiUpdate(ItemCollection dataDefinition, FileData fileData,
|
||||
ItemCollection poiConfig, WorkflowService workflowService) throws PluginException {
|
||||
|
||||
// update $modified for Now function
|
||||
dataDefinition.setItemValue("$modified", new Date());
|
||||
|
||||
if (poiConfig == null || !poiConfig.hasItem("findreplace")) {
|
||||
// no config found
|
||||
return;
|
||||
}
|
||||
List<String> replaceDevList = poiConfig.getItemValue("findreplace");
|
||||
String eval = poiConfig.getItemValueString("eval");
|
||||
|
||||
// load XSSFWorkbook
|
||||
try (InputStream imputStream = new ByteArrayInputStream(fileData.getContent())) {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(imputStream);
|
||||
// NOTE: we only take the first sheet !
|
||||
XSSFSheet sheet = workbook.getSheetAt(0);
|
||||
|
||||
updateXSSFWorkbook(workbook, dataDefinition, replaceDevList, workflowService);
|
||||
|
||||
// Update Eval list
|
||||
if (eval != null && !eval.isEmpty()) {
|
||||
// iterate over all cells to be evaluated
|
||||
String[] cellPositions = eval.split(";");
|
||||
for (String cellPos : cellPositions) {
|
||||
evalXSSFSheet(workbook, sheet, cellPos);
|
||||
}
|
||||
logger.fine("formula evaluation completed");
|
||||
}
|
||||
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
// write back the file
|
||||
workbook.write(byteArrayOutputStream);
|
||||
workbook.close();
|
||||
byte[] newContent = byteArrayOutputStream.toByteArray();
|
||||
fileData.setContent(newContent);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new PluginException(DataViewPOIHelper.class.getSimpleName(), ERROR_CONFIG,
|
||||
"failed to update excel export: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Cell by name or an optional absolute cell postion
|
||||
* <p>
|
||||
* Examples for refs are 'A1', 'AB3', 'MyCell' where 'MyCell' is a named cell.
|
||||
* <p>
|
||||
*
|
||||
*/
|
||||
public static XSSFCell getCellByRef(XSSFWorkbook doc, XSSFSheet sheet, String cellReference) {
|
||||
XSSFCell cell = null;
|
||||
|
||||
// first we test if the cellName is a named cell
|
||||
Name aNamedCell = doc.getName(cellReference);
|
||||
if (aNamedCell != null) {
|
||||
// yes its a named cell so we need to get the referrer Formula
|
||||
logger.finest("...resolving named cell = " + aNamedCell.getNameName());
|
||||
cellReference = aNamedCell.getRefersToFormula();
|
||||
// now we can find the cell by its ref
|
||||
}
|
||||
|
||||
CellReference cr = new CellReference(cellReference);
|
||||
XSSFRow row = sheet.getRow(cr.getRow());
|
||||
if (row == null) {
|
||||
logger.severe("Unable to resolve cell ref '" + cellReference + "'!");
|
||||
return null;
|
||||
}
|
||||
cell = row.getCell(cr.getCol());
|
||||
return cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the XSSFWorkbook document. The method can be overwritten
|
||||
* by subclasses to add additional logic
|
||||
*
|
||||
* @param workbook
|
||||
* @param workitem
|
||||
* @param replaceDevList
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static void updateXSSFWorkbook(XSSFWorkbook workbook, ItemCollection workitem, List<String> replaceDevList,
|
||||
WorkflowService workflowService)
|
||||
throws PluginException {
|
||||
|
||||
logger.fine("XSSFWorkbook loaded");
|
||||
// NOTE: we only take the first sheet !
|
||||
XSSFSheet sheet = workbook.getSheetAt(0);
|
||||
|
||||
for (String entityDev : replaceDevList) {
|
||||
ItemCollection entityData = XMLParser.parseItemStructure(entityDev);
|
||||
|
||||
if (entityData != null) {
|
||||
String find = entityData.getItemValueString("find");
|
||||
String replace = entityData.getItemValueString("replace");
|
||||
replace = workflowService.adaptText(replace, workitem);
|
||||
// optional itename
|
||||
String itemname = entityData.getItemValueString("itemname");
|
||||
|
||||
// replace with item value?
|
||||
if (!itemname.isEmpty()) {
|
||||
List<?> valueList = workitem.getItemValue(itemname);
|
||||
if (valueList.size() > 0) {
|
||||
// provide the first value only
|
||||
replaceXSSFSheetItemValue(workbook, sheet, find, valueList.get(0));
|
||||
}
|
||||
} else {
|
||||
replaceXSSFSheetStringValue(workbook, sheet, find, replace);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method replaces a given cell of a XSSFSheet with a typed item value
|
||||
*
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static void replaceXSSFSheetItemValue(XSSFWorkbook doc, XSSFSheet sheet, String find, Object itemValue)
|
||||
throws PluginException {
|
||||
logger.finest("update cell " + find);
|
||||
XSSFCell cell = getCellByRef(doc, sheet, find);
|
||||
if (cell == null) {
|
||||
logger.warning("Cell " + find + " not found.");
|
||||
return;
|
||||
}
|
||||
if (itemValue instanceof Date) {
|
||||
cell.setCellValue((Date) itemValue);
|
||||
} else if (itemValue instanceof Double) {
|
||||
cell.setCellValue((Double) itemValue);
|
||||
} else {
|
||||
// default to text
|
||||
cell.setCellValue(itemValue.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method replaces a given cell of a XSSFSheet with a string value
|
||||
*
|
||||
* @throws PluginException
|
||||
*/
|
||||
private static void replaceXSSFSheetStringValue(XSSFWorkbook doc, XSSFSheet sheet, String find, String replace)
|
||||
throws PluginException {
|
||||
logger.finest("update cell " + find);
|
||||
XSSFCell cell = getCellByRef(doc, sheet, find);
|
||||
if (cell == null) {
|
||||
logger.warning("Cell " + find + " not found.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// we try to set first as float value if possible
|
||||
float f = Float.parseFloat(replace);
|
||||
cell.setCellValue(f);
|
||||
} catch (NumberFormatException e) {
|
||||
// set value as string
|
||||
cell.setCellValue(replace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a given list of cells in a given XSWorkbook
|
||||
*
|
||||
* @param doc
|
||||
* @param sheet
|
||||
* @param cell
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static void evalXSSFSheet(XSSFWorkbook doc, XSSFSheet sheet, String cell) throws PluginException {
|
||||
FormulaEvaluator evaluator = doc.getCreationHelper().createFormulaEvaluator();
|
||||
XSSFCell c = getCellByRef(doc, sheet, cell);
|
||||
if (c == null) {
|
||||
logger.warning("Cell " + cell + " not found.");
|
||||
return;
|
||||
}
|
||||
if (c.getCellType() == CellType.FORMULA) {
|
||||
logger.finest("...eval cell " + cell);
|
||||
try {
|
||||
CellType evalResult = evaluator.evaluateFormulaCell(c);
|
||||
if (evalResult == CellType.ERROR) {
|
||||
logger.warning("...unable to evaluate cell " + cell);
|
||||
}
|
||||
} catch (Exception poie) {
|
||||
logger.warning("...failed to evaluate cell " + cell + " : " + poie.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,10 +10,12 @@
|
|||
<f:viewAction action="#{dataViewDefinitionController.onLoad()}" />
|
||||
</f:metadata>
|
||||
|
||||
|
||||
|
||||
<ui:define name="content">
|
||||
|
||||
<f:view>
|
||||
<h:form id="textblock_form_id" pt:autocomplete="on" enctype="multipart/form-data">
|
||||
<h:form id="dataview_definition_form_id" pt:autocomplete="on" enctype="multipart/form-data">
|
||||
|
||||
<div class="imixs-form">
|
||||
<div class="imixs-header">
|
||||
|
|
@ -55,11 +57,8 @@
|
|||
</p>
|
||||
<dl>
|
||||
<dt>
|
||||
Name:<span class="imixs-required"> *
|
||||
|
||||
</span>
|
||||
Name:<span class="imixs-required"> * </span>
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
<h:inputText required="true" id="txtname_id"
|
||||
value="#{dataViewDefinitionController.data.item['Name']}" />
|
||||
|
|
@ -88,6 +87,28 @@
|
|||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="imixs-form-section-2">
|
||||
<dl>
|
||||
<dt>
|
||||
Sort By:
|
||||
</dt>
|
||||
<dd>
|
||||
<h:inputText required="true"
|
||||
value="#{dataViewDefinitionController.data.item['sort.by']}" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
Reverse Order:
|
||||
</dt>
|
||||
<dd>
|
||||
<h:selectBooleanCheckbox required="false" label=""
|
||||
value="#{dataViewDefinitionController.data.item['sort.reverse']}">
|
||||
</h:selectBooleanCheckbox>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
|
@ -102,7 +123,8 @@
|
|||
values. Each item of
|
||||
the attribute list can define an optional label, xs datatype and format.
|
||||
<br />
|
||||
Convert - xml datatypes: xs:string (default), xs:decimal, xs:date,
|
||||
Convert - xml datatypes: xs:string (default), xs:int, xs:double, xs:float,
|
||||
xs:date,
|
||||
xs:dateTime,
|
||||
xs:anyURI
|
||||
|
||||
|
|
@ -212,7 +234,7 @@
|
|||
|
||||
<div id="tab-3">
|
||||
<div class="imixs-form-panel">
|
||||
<div class="imixs-form-section-1">
|
||||
<div class="imixs-form-section-2">
|
||||
<h1><span class="typcn typcn-news"></span> Template<span
|
||||
style="font-size: 1rem;margin-left:20px;">
|
||||
<h:outputLink
|
||||
|
|
@ -221,25 +243,59 @@
|
|||
style="font-size: 1.2rem;"></span> Test View
|
||||
</h:outputLink>
|
||||
</span></h1>
|
||||
<dl>
|
||||
<dl>
|
||||
<dt>
|
||||
POI Update:
|
||||
</dt>
|
||||
<dd>
|
||||
<h:inputTextarea
|
||||
value="#{dataViewDefinitionController.data.item['poi.update']}"
|
||||
style="height: 27em; font-family: 'Courier New', Courier, monospace; autocomplete: off;" />
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
<span class="typcn typcn-lightbulb"></span>
|
||||
The 'Target Name' defines the name of the file download. The 'Reference Cell
|
||||
marks the row to insert the dataset. POI update Definitions are optional.
|
||||
|
||||
<div class="textblock-file-input" style="width: 50%;">
|
||||
</p>
|
||||
<dl>
|
||||
<dt>
|
||||
Target Name:
|
||||
</dt>
|
||||
<dd>
|
||||
<h:inputText
|
||||
value="#{dataViewDefinitionController.data.item['poi.targetfilename']}" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
Reference Cell:
|
||||
</dt>
|
||||
<dd>
|
||||
<h:inputText style="width: 5em;"
|
||||
value="#{dataViewDefinitionController.data.item['poi.referenceCell']}" />
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="imixs-form-section-1">
|
||||
<dl>
|
||||
<dt>
|
||||
POI Definition:
|
||||
</dt>
|
||||
<dd>
|
||||
<h:inputTextarea
|
||||
value="#{dataViewDefinitionController.data.item['poi.update']}"
|
||||
style="height: 27em; font-family: 'Courier New', Courier, monospace; autocomplete: off;" />
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
Source File :
|
||||
</dt>
|
||||
<dd>
|
||||
<i:imixsFileUpload showattachments="true"
|
||||
workitem="#{dataViewDefinitionController.data}"
|
||||
context_url="#{facesContext.externalContext.requestContextPath}/api/snapshot/#{dataViewDefinitionController.data.item['$uniqueid']}" />
|
||||
</div>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -277,6 +333,7 @@
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*]]>*/
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,14 +9,39 @@
|
|||
<f:metadata>
|
||||
<f:viewAction action="#{dataViewController.onLoad()}" />
|
||||
</f:metadata>
|
||||
<!-- Diese Form exportiert Ausgangsrechnungen nach Excel
|
||||
-->
|
||||
<ui:define name="scripts">
|
||||
<script type="text/javascript">
|
||||
/*<![CDATA[*/
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
});
|
||||
|
||||
//ajax refresh...
|
||||
function updateDataView(data, context) {
|
||||
var viewBody = $("#dataview-controlls-id");
|
||||
if (data.status === "begin") {
|
||||
viewBody.addClass("loading");
|
||||
} else if (data.status === "success") {
|
||||
imixsOfficeMain.layoutAjaxEvent(data);
|
||||
}
|
||||
}
|
||||
|
||||
function handleSubmit(event) {
|
||||
// remove ajax loader 5sec after trigger excel export
|
||||
setTimeout(function () {
|
||||
document.body.classList.remove('loading');
|
||||
}, 5000);
|
||||
}
|
||||
/*]]>*/
|
||||
</script>
|
||||
</ui:define>
|
||||
<ui:define name="content">
|
||||
|
||||
<f:view>
|
||||
<h:form id="dataview_id" pt:autocomplete="on">
|
||||
|
||||
|
||||
|
||||
<h:form id="dataview_id" pt:autocomplete="on" onsubmit="handleSubmit(event)">
|
||||
<div class="imixs-form">
|
||||
<div class="imixs-header">
|
||||
<h1>
|
||||
|
|
@ -50,14 +75,16 @@
|
|||
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="imixs-form-section">
|
||||
<div id="dataview-controlls-id" class="imixs-form-section">
|
||||
<div style="float:left;">
|
||||
<h:commandButton value="Anzeigen" action="#{dataViewController.run()}">
|
||||
<f:ajax execute="@form dataview_result_id" render="dataview_result_id"
|
||||
onevent="updateDataView" />
|
||||
</h:commandButton>
|
||||
|
||||
<h:commandButton value="Excel Export" action="#{dataViewController.run()}" />
|
||||
<h:commandButton actionListener="#{dataViewController.export()}" value="Excel Export">
|
||||
</h:commandButton>
|
||||
|
||||
<h:commandButton value="Close" action="/pages/notes?faces-redirect=true" />
|
||||
</div>
|
||||
|
||||
|
|
@ -133,10 +160,17 @@
|
|||
<f:facet name="header">#{columnDef.item['item.label']}</f:facet>
|
||||
<h:outputText value="#{record.item[columnDef.item['item.name']]}">
|
||||
<f:convertDateTime timeZone="#{message.timeZone}" type="both"
|
||||
pattern="#{message.dateTimePattern}" />
|
||||
pattern="#{message.datePatternShort}" />
|
||||
</h:outputText>
|
||||
</h:column>
|
||||
|
||||
|
||||
<h:column rendered="#{columnDef.item['item.type'] eq 'xs:dateTime'}">
|
||||
<f:facet name="header">#{columnDef.item['item.label']}</f:facet>
|
||||
<h:outputText value="#{record.item[columnDef.item['item.name']]}">
|
||||
<f:convertDateTime timeZone="#{message.timeZone}" type="both"
|
||||
pattern="#{message.dateTimePatternShort}" />
|
||||
</h:outputText>
|
||||
</h:column>
|
||||
</c:forEach>
|
||||
|
||||
|
|
@ -146,30 +180,11 @@
|
|||
</h:dataTable>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Init script -->
|
||||
<script type="text/javascript">
|
||||
/*<![CDATA[*/
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
});
|
||||
|
||||
//ajax refresh...
|
||||
function updateDataView(data, context) {
|
||||
if (data.status === 'success') {
|
||||
imixsOfficeMain.layoutAjaxEvent(data);
|
||||
}
|
||||
}
|
||||
|
||||
/*]]>*/
|
||||
</script>
|
||||
|
||||
</f:view>
|
||||
</ui:define>
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in a new issue