/*
Copyright 2017 Roman Torkhov, BarD Software s.r.o
This file is part of GanttProject, an opensource project management tool.
GanttProject 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 3 of the License, or
(at your option) any later version.
GanttProject 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 GanttProject. If not, see <http://www.gnu.org/licenses/>.
*/
package biz.ganttproject.impex.csv;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author torkhov
*/
class XlsReaderImpl implements SpreadsheetReader {
private final Workbook myBook;
private final Map<String, Integer> myHeaders;
XlsReaderImpl(InputStream is, List<String> columnHeaders) throws IOException {
myBook = new HSSFWorkbook(is);
myHeaders = initializeHeader(columnHeaders);
}
@Override
public void close() throws IOException {
myBook.close();
}
@Override
public Iterator<SpreadsheetRecord> iterator() {
return Iterators.transform(myBook.getSheetAt(0).iterator(), (input) -> new XlsRecordImpl(getCellValues(input), myHeaders));
}
private List<String> getCellValues(Row row) {
return Lists.newArrayList(Iterables.transform(row, Cell::getStringCellValue));
}
/**
* This method was taken from {@link org.apache.commons.csv.CSVParser#initializeHeader}
* Create the name to index mapping if the column headers not {@code null}.
* @param columnHeaders column headers
* @return the name to index mapping
*/
private Map<String, Integer> initializeHeader(List<String> columnHeaders) {
Map<String, Integer> hdrMap = null;
List<String> formatHeader = columnHeaders;
if (formatHeader != null) {
hdrMap = new LinkedHashMap<>();
List<String> headerRecord = null;
if (formatHeader.isEmpty()) {
// read the header from the first line of the file
Row row = myBook.getSheetAt(0).getRow(0);
if (row != null) {
headerRecord = getCellValues(row);
}
} else {
headerRecord = formatHeader;
}
// build the name to index mappings
if (headerRecord != null) {
for (int i = 0; i < headerRecord.size(); i++) {
String header = headerRecord.get(i);
if (hdrMap.containsKey(header)) {
throw new IllegalArgumentException("The header contains a duplicate name: \"" + header + "\" in " + headerRecord);
}
hdrMap.put(header, i);
}
}
}
return hdrMap;
}
}