net.sf.jxls.parser.CellParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jxls-core Show documentation
Show all versions of jxls-core Show documentation
jXLS is a small and easy-to-use Java library for generating Excel files using XLS templates
package net.sf.jxls.parser;
import net.sf.jxls.exception.ParsePropertyException;
import net.sf.jxls.formula.Formula;
import net.sf.jxls.tag.Block;
import net.sf.jxls.tag.Tag;
import net.sf.jxls.tag.TagContext;
import net.sf.jxls.transformer.Configuration;
import net.sf.jxls.transformer.Row;
import net.sf.jxls.util.Util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.ss.usermodel.Sheet;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.StringReader;
import java.util.Map;
/**
* Class for parsing excel cell
* @author Leonid Vysochyn
*/
public class CellParser {
protected static final Log log = LogFactory.getLog(CellParser.class);
private final Cell cell;
private Configuration configuration;
public CellParser(org.apache.poi.ss.usermodel.Cell hssfCell, Row row, Configuration configuration) {
this.cell = new Cell( hssfCell, row );
if( configuration!=null ){
this.configuration = configuration;
}else{
this.configuration = new Configuration();
}
}
public CellParser(Cell cell) {
this.cell = cell;
}
public Cell getCell() {
return cell;
}
public Cell parseCell(Map beans){
org.apache.poi.ss.usermodel.Cell c = cell.getPoiCell();
if (c != null) {
try {
if( c.getCellType() == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING ){
cell.setPoiCellValue(c.getRichStringCellValue().getString());
parseCellValue( beans);
}
} catch (ParsePropertyException e) {
log.error("Can't get value for property=" + cell.getCollectionProperty().getProperty(), e);
throw new RuntimeException(e);
}
updateMergedRegions();
}
return cell;
}
public Formula parseCellFormula(){
if( cell.getPoiCell() != null && (cell.getPoiCell().getCellType() == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING)) {
cell.setPoiCellValue( cell.getPoiCell().getRichStringCellValue().getString() );
if( cell.getPoiCellValue().startsWith(configuration.getStartFormulaToken()) && cell.getPoiCellValue().lastIndexOf(configuration.getEndFormulaToken()) > 0 ){
parseFormula();
}
}
return cell.getFormula();
}
private void parseFormula() {
// process formula cell
final String poiCellValue = cell.getPoiCellValue();
int i = poiCellValue.lastIndexOf(configuration.getEndFormulaToken());
String expr = poiCellValue.substring(2, i);
cell.setFormula(new Formula(expr, cell.getRow().getSheet()));
cell.getFormula().setRowNum(cell.getRow().getPoiRow().getRowNum());
cell.getFormula().setCellNum(cell.getPoiCell().getColumnIndex());
if (i + 1 < poiCellValue.length()) {
String tail = poiCellValue.substring(i + 1);
int j = tail.indexOf(configuration.getMetaInfoToken());
if( j >= 0 ){
cell.setMetaInfo(tail.substring(j));
if( j > 0 ){
cell.setLabel(tail.substring(0, j));
}
cell.setCollectionName(tail.substring(j + 2));
}else{
cell.setLabel(tail);
}
}
cell.setStringCellValue(poiCellValue.substring(0, i + 1));
}
private void parseCellExpression(Map beans) {
cell.setCollectionProperty(null);
String curValue = cell.getPoiCellValue();
String cv = curValue;
int depRowNum = 0;
int j = curValue.lastIndexOf(configuration.getMetaInfoToken());
if( j>=0 ){
cell.setStringCellValue(cv.substring(0, j));
cell.setMetaInfo(cv.substring(j + 2));
String tail = curValue.substring(j + 2);
// processing additional parameters
// check if there is collection property name specified
int k = tail.indexOf(":");
if( k >= 0 ){
try {
depRowNum = Integer.parseInt( tail.substring(k+1) );
} catch (NumberFormatException e) {
// ignore it if not an integer
}
cell.setCollectionName(tail.substring(0, k));
}else{
cell.setCollectionName(tail);
}
curValue = curValue.substring(0, j);
}else{
cell.setStringCellValue(cv);
}
try {
while( curValue.length()>0 ){
int i = curValue.indexOf(configuration.getStartExpressionToken());
if( i>=0 ) {
int k = curValue.indexOf(configuration.getEndExpressionToken(), i+2);
if( k>=0 ){
// new bean property found
String expr = curValue.substring(i+2, k);
if( i>0 ){
String before = curValue.substring(0, i);
cell.getExpressions().add( new Expression( before, configuration ) );
}
Expression expression = new Expression(expr, beans, configuration);
if( expression.getCollectionProperty() != null ){
if( cell.getCollectionProperty() == null ){
cell.setCollectionName(expression.getCollectionProperty().getFullCollectionName());
cell.setCollectionProperty(expression.getCollectionProperty());
cell.setDependentRowNumber(depRowNum);
}else{
if( log.isInfoEnabled() ){
log.info("Only the same collection property in a cell is allowed.");
}
}
}
cell.getExpressions().add( expression );
curValue = curValue.substring(k+1, curValue.length());
}else{
cell.getExpressions().add( new Expression(curValue, configuration) );
curValue = "";
}
}else{
if( curValue.length()!=cv.length() ){
cell.getExpressions().add( new Expression( curValue, configuration ));
}
curValue = "";
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("Can't parse expression", e);
}
}
private void parseCellValue(Map beans) throws ParsePropertyException {
String cv = cell.getPoiCellValue();
if( cv !=null ){
if( cv.startsWith(configuration.getStartFormulaToken()) && cv.lastIndexOf(configuration.getEndFormulaToken()) > 0 ){
parseFormula();
}
else if(cv.startsWith( configuration.getTagPrefixWithBrace() )){
// String tagName = cell.getPoiCellValue().split("(?<=<" + configuration.getTagPrefix() + ")\\w+", 2)[0];
String tagName = getTagName( cv );
if( tagName!=null ){
final Row row = cell.getRow();
final org.apache.poi.ss.usermodel.Row poiRow = row.getPoiRow();
final org.apache.poi.ss.usermodel.Cell poiCell = cell.getPoiCell();
final int rowNum = poiRow.getRowNum();
final int columnIndex = poiCell.getColumnIndex();
if (cv.endsWith("/>")) {
Block tagBody = new Block(rowNum, columnIndex, rowNum, columnIndex);
parseTag( tagName, tagBody, beans, false);
} else {
org.apache.poi.ss.usermodel.Cell hssfCell = findMatchingPairInRow(poiRow, tagName );
if( hssfCell!=null ){
// closing tag is in the same row
Block tagBody = new Block(rowNum, columnIndex, rowNum, hssfCell.getColumnIndex());
parseTag( tagName, tagBody, beans, true);
}else{
org.apache.poi.ss.usermodel.Row hssfRow = findMatchingPair( tagName );
if( hssfRow!=null ){
// closing tag is in hssfRow
int lastTagBodyRowNum = hssfRow.getRowNum() ;
Block tagBody = new Block(null, rowNum, lastTagBodyRowNum);
parseTag( tagName, tagBody, beans , true);
}else{
log.error("Can't find matching tag pair for " + cv);
}
}
}
}
}else{
parseCellExpression(beans);
}
}
}
private org.apache.poi.ss.usermodel.Cell findMatchingPairInRow(org.apache.poi.ss.usermodel.Row hssfRow, String tagName) {
int count = 0;
if( hssfRow!=null ){
for(int j = (cell.getPoiCell().getColumnIndex() + 1); j <= hssfRow.getLastCellNum(); j++){
org.apache.poi.ss.usermodel.Cell hssfCell = hssfRow.getCell( j );
if( hssfCell != null && hssfCell.getCellType() == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING ){
String cellValue = hssfCell.getRichStringCellValue().getString();
if( cellValue.matches("<" + configuration.getTagPrefix() + tagName + "\\b.*")){
count++;
}else{
if( cellValue.matches("" + configuration.getTagPrefix() + tagName + ">" )){
if( count == 0 ){
return hssfCell;
}
count--;
}
}
}
}
}
return null;
}
private String getTagName(String xmlTag){
int i = configuration.getTagPrefix().length() + 1;
int j = i;
while( j < xmlTag.length() && Character.isLetterOrDigit( xmlTag.charAt( j ) ) ){
j++;
}
if( j == xmlTag.length() ){
log.warn("can't determine tag name");
return null;
}
return xmlTag.substring(i, j);
}
private org.apache.poi.ss.usermodel.Row findMatchingPair(String tagName) {
Sheet hssfSheet = cell.getRow().getSheet().getPoiSheet();
int count = 0;
for( int i = cell.getRow().getPoiRow().getRowNum() + 1; i <= hssfSheet.getLastRowNum(); i++ ){
org.apache.poi.ss.usermodel.Row hssfRow = hssfSheet.getRow( i );
if( hssfRow!=null && hssfRow.getFirstCellNum() >= 0 && hssfRow.getLastCellNum() >= 0 ){
for(short j = hssfRow.getFirstCellNum(); j <= hssfRow.getLastCellNum(); j++){
org.apache.poi.ss.usermodel.Cell hssfCell = hssfRow.getCell( (int)j );
if( hssfCell != null && hssfCell.getCellType() == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING ){
String cellValue = hssfCell.getRichStringCellValue().getString();
if( cellValue.matches("<" + configuration.getTagPrefix() + tagName + "\\b.*")){
count++;
}else{
if( cellValue.matches("" + configuration.getTagPrefix() + tagName + ">" )){
if( count == 0 ){
return hssfRow;
}
count--;
}
}
}
}
}
}
return null;
}
private void parseTag(String tagName, Block tagBody, Map beans, boolean appendCloseTag){
String xml = null;
try {
if (appendCloseTag) {
xml = configuration.getJXLSRoot() + cell.getPoiCellValue() + "" + configuration.getTagPrefix() + tagName + ">" + configuration.getJXLSRootEnd();
} else {
xml = configuration.getJXLSRoot() + cell.getPoiCellValue() + configuration.getJXLSRootEnd();
}
if (configuration.getEncodeXMLAttributes()) {
xml = Util.escapeAttributes( xml );
}
Tag tag = (Tag) configuration.getDigester().parse(new StringReader( xml ) );
if (tag == null) {
throw new RuntimeException("Invalid tag: " + tagName);
}
cell.setTag( tag );
TagContext tagContext = new TagContext( cell.getRow().getSheet(), tagBody, beans );
tag.init( tagContext );
} catch (IOException e) {
log.warn( "Can't parse cell tag " + cell.getPoiCellValue() + ": fullXML: " + xml, e);
throw new RuntimeException("Can't parse cell tag " + cell.getPoiCellValue() + ": fullXML: " + xml, e);
} catch (SAXException e) {
log.warn( "Can't parse cell tag " + cell.getPoiCellValue() + ": fullXML: " + xml, e);
throw new RuntimeException("Can't parse cell tag " + cell.getPoiCellValue() + ": fullXML: " + xml, e);
}
}
private void updateMergedRegions() {
Row row = cell.getRow();
cell.setMergedRegion(
Util.getMergedRegion( row.getSheet().getPoiSheet(), row.getPoiRow().getRowNum(), cell.getPoiCell().getColumnIndex())
);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy