/* * This file is part of the OpenSCADA project * Copyright (C) 2006-2010 TH4 SYSTEMS GmbH (http://th4-systems.com) * * OpenSCADA is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenSCADA 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 Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenSCADA. If not, see * <http://opensource.org/licenses/lgpl-3.0.html> for a copy of the LGPLv3 License. */ package org.openscada.ae.ui.views.export.excel.impl; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.poi.hpsf.CustomProperties; import org.apache.poi.hpsf.DocumentSummaryInformation; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFFooter; import org.apache.poi.hssf.usermodel.HSSFHeader; import org.apache.poi.hssf.usermodel.HSSFPatternFormatting; import org.apache.poi.hssf.usermodel.HSSFPrintSetup; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HeaderFooter; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.PrintSetup; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.IStructuredSelection; import org.openscada.ae.Event; import org.openscada.ae.ui.views.export.excel.Activator; import org.openscada.ae.ui.views.export.excel.Cell; import org.openscada.ae.ui.views.export.excel.config.DynamicField; import org.openscada.ae.ui.views.export.excel.config.Field; import org.openscada.ae.ui.views.export.excel.config.StaticField; import org.openscada.ui.databinding.AdapterHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ExportImpl { private final static Logger logger = LoggerFactory.getLogger ( ExportImpl.class ); private IStructuredSelection selection; private File file; public ExportImpl () { } public void setSelection ( final IStructuredSelection selection ) { this.selection = selection; } public void setFile ( final File file ) { this.file = file; } public void check () { if ( this.file == null ) { throw new IllegalStateException ( Messages.ExportImpl_ErrorMessage_NoFileSelected ); } if ( this.selection == null ) { throw new IllegalStateException ( Messages.ExportImpl_ErrorMessage_NoEventsSelected ); } } public IStatus write ( final IProgressMonitor monitor ) { if ( this.selection == null ) { return Status.OK_STATUS; } if ( this.file.exists () ) { if ( !this.file.delete () ) { return new Status ( IStatus.ERROR, Activator.PLUGIN_ID, String.format ( Messages.ExportImpl_ErrorMessage_FailedToDeleteFile, this.file ) ); } } final List<Event> events = new ArrayList<Event> (); final Iterator<?> i = this.selection.iterator (); while ( i.hasNext () ) { final Event e = AdapterHelper.adapt ( i.next (), Event.class ); if ( e != null ) { events.add ( e ); } } try { return storeExcel ( this.file, events, getFields ( events ), monitor ); } catch ( final Exception e ) { logger.warn ( Messages.ExportImpl_ErrorMessage_FailedToExport, e ); return new Status ( IStatus.ERROR, Activator.PLUGIN_ID, Messages.ExportImpl_ErrorMessage_FailedToExport, e ); } } private List<Field> getFields ( final Collection<Event> events ) { final Set<Field> fields = new HashSet<Field> (); fields.add ( new StaticField ( "id" ) { //$NON-NLS-1$ @Override public void render ( final Event event, final Cell cell ) { cell.setDataAsText ( event.getId ().toString () ); } } ); fields.add ( new StaticField ( "sourceTimestamp" ) { //$NON-NLS-1$ @Override public void render ( final Event event, final Cell cell ) { cell.setDataAsDate ( event.getSourceTimestamp () ); } } ); fields.add ( new StaticField ( "entryTimestamp" ) { //$NON-NLS-1$ @Override public void render ( final Event event, final Cell cell ) { cell.setDataAsDate ( event.getEntryTimestamp () ); } } ); for ( final Event event : events ) { for ( final String key : event.getAttributes ().keySet () ) { fields.add ( new DynamicField ( key ) ); } } return new ArrayList<Field> ( fields ); } private IStatus storeExcel ( final File file, final List<Event> events, final List<Field> columns, final IProgressMonitor monitor ) throws IOException { final HSSFWorkbook workbook = new HSSFWorkbook (); final HSSFDataFormat dateFormat = workbook.createDataFormat (); final HSSFCellStyle dateCellStyle = workbook.createCellStyle (); dateCellStyle.setDataFormat ( dateFormat.getFormat ( "YYYY-MM-DD hh:mm:ss.000" ) ); try { monitor.beginTask ( Messages.ExportImpl_Progress_ExportingEvents, events.size () + 3 + columns.size () ); try { monitor.subTask ( Messages.ExportImpl_Progress_CreateWorkbook ); monitor.worked ( 1 ); final HSSFSheet sheet = createSheet ( events, workbook, columns ); monitor.worked ( 1 ); monitor.setTaskName ( Messages.ExportImpl_Progress_ExportEvents ); for ( int i = 0; i < events.size (); i++ ) { final HSSFRow row = sheet.createRow ( i + 1 ); final Event e = events.get ( i ); for ( int j = 0; j < columns.size (); j++ ) { final Field field = columns.get ( j ); final ExcelCell cell = new ExcelCell ( row, j, dateCellStyle ); field.render ( e, cell ); } monitor.worked ( 1 ); if ( monitor.isCanceled () ) { return Status.CANCEL_STATUS; } } workbook.setRepeatingRowsAndColumns ( 0, -1, -1, 0, 1 ); monitor.setTaskName ( "Auto sizing" ); for ( int i = 0; i < columns.size (); i++ ) { monitor.subTask ( String.format ( "Auto sizing column: %s", columns.get ( i ).getHeader () ) ); sheet.autoSizeColumn ( i ); monitor.worked ( 1 ); if ( monitor.isCanceled () ) { return Status.CANCEL_STATUS; } } } finally { monitor.subTask ( Messages.ExportImpl_Progress_CloseFile ); if ( workbook != null ) { makeDocInfo ( workbook ); final FileOutputStream stream = new FileOutputStream ( file ); workbook.write ( stream ); stream.close (); } monitor.worked ( 1 ); } } finally { monitor.done (); } return Status.OK_STATUS; } private void makeDocInfo ( final HSSFWorkbook workbook ) { workbook.createInformationProperties (); final DocumentSummaryInformation dsi = workbook.getDocumentSummaryInformation (); dsi.setCompany ( "TH4 SYSTEMS GmbH" ); final CustomProperties cp = new CustomProperties (); cp.put ( "openSCADA Export Version", Activator.getDefault ().getBundle ().getVersion ().toString () ); dsi.setCustomProperties ( cp ); } private HSSFSheet createSheet ( final List<Event> events, final HSSFWorkbook workbook, final List<Field> columns ) { final HSSFSheet sheet = workbook.createSheet ( Messages.ExportImpl_ExcelSheet_Name ); final HSSFHeader header = sheet.getHeader (); header.setLeft ( Messages.ExportImpl_ExcelSheet_Header ); header.setRight ( HeaderFooter.date () + " " + HeaderFooter.time () );//$NON-NLS-1$ final HSSFFooter footer = sheet.getFooter (); footer.setLeft ( String.format ( Messages.ExportImpl_ExcelSheet_Footer_1, events.size () ) ); footer.setRight ( Messages.ExportImpl_ExcelSheet_Footer_2 + HeaderFooter.page () + Messages.ExportImpl_ExcelSheet_Footer_3 + HeaderFooter.numPages () ); makeHeader ( columns, sheet ); final HSSFPrintSetup printSetup = sheet.getPrintSetup (); printSetup.setLandscape ( true ); printSetup.setFitWidth ( (short)1 ); printSetup.setFitHeight ( (short)0 ); printSetup.setPaperSize ( PrintSetup.A4_PAPERSIZE ); sheet.setAutoFilter ( new CellRangeAddress ( 0, 0, 0, columns.size () - 1 ) ); sheet.createFreezePane ( 0, 1 ); sheet.setFitToPage ( true ); sheet.setAutobreaks ( true ); printSetup.setFooterMargin ( 0.25 ); sheet.setMargin ( Sheet.LeftMargin, 0.25 ); sheet.setMargin ( Sheet.RightMargin, 0.25 ); sheet.setMargin ( Sheet.TopMargin, 0.25 ); sheet.setMargin ( Sheet.BottomMargin, 0.5 ); return sheet; } private void makeHeader ( final List<Field> columns, final HSSFSheet sheet ) { final Font font = sheet.getWorkbook ().createFont (); font.setFontName ( "Arial" ); font.setBoldweight ( Font.BOLDWEIGHT_BOLD ); font.setColor ( HSSFColor.WHITE.index ); final CellStyle style = sheet.getWorkbook ().createCellStyle (); style.setFont ( font ); style.setFillForegroundColor ( HSSFColor.BLACK.index ); style.setFillPattern ( HSSFPatternFormatting.SOLID_FOREGROUND ); final HSSFRow row = sheet.createRow ( 0 ); for ( int i = 0; i < columns.size (); i++ ) { final Field field = columns.get ( i ); final HSSFCell cell = row.createCell ( i ); cell.setCellValue ( field.getHeader () ); cell.setCellStyle ( style ); } } public File getFile () { return this.file; } }