All Downloads are FREE. Search and download functionalities are using the official Maven repository.

step.datapool.excel.WorkbookSet Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (C) 2020, exense GmbH
 *  
 * This file is part of STEP
 *  
 * STEP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * STEP 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 Affero General Public License for more details.
 *  
 * You should have received a copy of the GNU Affero General Public License
 * along with STEP.  If not, see .
 ******************************************************************************/
package step.datapool.excel;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.model.ExternalLinksTable;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WorkbookSet implements AutoCloseable{
	
	private LinkedWorkbookFileResolver resolver;
	
	private List workbooks = new ArrayList<>();
	
	private File mainWorkbookFile;
	
	private WorkbookFile mainWorkbook;
	
	private FormulaEvaluator mainFormulaEvaluator;
	
	private static final Logger logger = LoggerFactory.getLogger(WorkbookSet.class);

	public WorkbookSet(File mainWorkbookFile, Integer maxWorkbookSize, LinkedWorkbookFileResolver resolver, boolean createIfNotExists, boolean forUpdate) {
		this.resolver = resolver;
		
		this.mainWorkbookFile = mainWorkbookFile;
		
		mainWorkbook = openWorkbook(mainWorkbookFile, maxWorkbookSize, createIfNotExists, forUpdate);
		mainFormulaEvaluator = mainWorkbook.getWorkbook().getCreationHelper().createFormulaEvaluator();
		
		openReferencedWorkbooks(maxWorkbookSize, mainWorkbook.getWorkbook(), mainFormulaEvaluator);
	}	
	
	public WorkbookSet(File mainWorkbookFile, Integer maxWorkbookSize, boolean createIfNotExists, boolean forUpdate) {
		this(mainWorkbookFile, maxWorkbookSize, new LinkedWorkbookFileResolver() {
			@Override
			public File resolve(String linkedFilename) {
				if(linkedFilename.startsWith("file:///")) {
					return new File(linkedFilename.substring(8));
				} else {
					return resolveRelativePath(mainWorkbookFile, linkedFilename);
				}
			}
		}, createIfNotExists, forUpdate);
	}
	
	private static File resolveRelativePath(File mainWorkbookFile, String linkedFilename) {
		File parent = mainWorkbookFile.getParentFile();
		if(parent != null) {
			File absoluteLinkedFile = new File(parent + "/" + linkedFilename);
			if(absoluteLinkedFile.exists()) {
				return absoluteLinkedFile;
			} else {
				return resolveRelativePath(parent, linkedFilename);
			}
		} else {
			return null;
		}
	}
	
	public void save() throws IOException {
		mainWorkbook.save();
	}
	
	public void close() {
		for (WorkbookFile workbook : workbooks) {
			workbook.close();
		}
		workbooks = null;
	}

	public File getMainWorkbookFile() {
		return mainWorkbookFile;
	}

	public Workbook getMainWorkbook() {
		return mainWorkbook.getWorkbook();
	}

	public FormulaEvaluator getMainFormulaEvaluator() {
		return mainFormulaEvaluator;
	}

	private void openReferencedWorkbooks(Integer maxWorkbookSize, Workbook workbook, FormulaEvaluator evaluator) {
		Map workbooks = new HashMap();
		
		if(workbook instanceof XSSFWorkbook) {
			if(((XSSFWorkbook)workbook).getExternalLinksTable()!=null) {
				for (ExternalLinksTable sheet : ((XSSFWorkbook)workbook).getExternalLinksTable()) {
					String file = sheet.getLinkedFileName();
					File f = resolver.resolve(file);
					if(f!=null) {
						try {
							WorkbookFile book = openWorkbook(f, maxWorkbookSize, false, false);
							workbooks.put(file, book.getWorkbook().getCreationHelper().createFormulaEvaluator());
						} catch(Exception e) {
							logger.error("An error occured while opening referenced workbook '"+file+"'. Main workbook: '"+mainWorkbookFile+"'");
						}
					} else {
						logger.warn("Unable to resolve external workbook '"+file+"'. Main workbook: '"+mainWorkbookFile+"'");
					}
				}
			}
		}
		
		workbooks.put("this", evaluator);			
		evaluator.setupReferencedWorkbooks(workbooks);
	}
	
	private WorkbookFile openWorkbook(File mainWorkbook, Integer maxWorkbookSize, boolean createIfNotExists, boolean forUpdate) {
		WorkbookFile openedOprkbook = new WorkbookFile();
		openedOprkbook.open(mainWorkbook, maxWorkbookSize, createIfNotExists, forUpdate);
		
		workbooks.add(openedOprkbook);
		return openedOprkbook;
	}
	
	public interface LinkedWorkbookFileResolver {
		
		public File resolve(String linkedFilename);
		
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy