org.ttzero.excel.reader.RowBlockParser Maven / Gradle / Ivy
/*
* Copyright (c) 2019-2020, [email protected] All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ttzero.excel.reader;
import org.ttzero.excel.entity.e3.BlankParser;
import org.ttzero.excel.entity.e3.Block;
import org.ttzero.excel.entity.e3.BoolErrParser;
import org.ttzero.excel.entity.e3.DBCellParser;
import org.ttzero.excel.entity.e3.FormulaParser;
import org.ttzero.excel.entity.e3.LabelParser;
import org.ttzero.excel.entity.e3.LabelSSTParser;
import org.ttzero.excel.entity.e3.MulBlank;
import org.ttzero.excel.entity.e3.MulBlankParser;
import org.ttzero.excel.entity.e3.MulRK;
import org.ttzero.excel.entity.e3.MulRKParser;
import org.ttzero.excel.entity.e3.NumberParser;
import org.ttzero.excel.entity.e3.ParserIdentifier;
import org.ttzero.excel.entity.e3.RKParser;
import org.ttzero.excel.entity.e3.RKValue;
import org.ttzero.excel.entity.e3.RichStringParser;
import static org.ttzero.excel.manager.Const.ROW_BLOCK_SIZE;
import static org.ttzero.excel.reader.Cell.SST;
import static org.ttzero.excel.reader.Cell.BLANK;
/**
* 4.7.2 Row Block
*
* All cells in the Cell Table are divided into blocks
* of 32 consecutive rows, called Row Blocks. The first
* Row Block starts with the first used row in that sheet.
* Inside each Row Block there will occur ROW records describing
* the properties of the rows, and cell records with all
* the cell contents in this Row Block.
*
* Each Row Block contains ROW records describing the row
* properties (in ascending order), followed by all cell records
* in this block. The cell records are stored row by row (ascending),
* and in each row from left to right. A used row either
* contains any (filled or formatted) cells or is changed in
* another way (for instance height or default formatting). If a row
* is not used, there will not occur a ROW record in the Row Block
*
* Example: The first used cell in the sheet is located in
* row 10, or row 10 is the first formatted row. The first Row
* Block will contain the rows {@code 10…41}, the second Row Block
* will contain the rows {@code 42…73}, and so on.
*
* @author guanquan.wang at 2019-03-07 15:57
*/
public class RowBlockParser {
public static RowBlock get(Block block) {
RowBlock rb = RowBlock.share();
int i = 0;
for (; i < ROW_BLOCK_SIZE; i++) {
short id = block.nextIdentifier();
if (id == ParserIdentifier.ROW) {
RowParser.get(block, rb.rows[i]);
rb.rows[i].clear(); // Clear value
} else {
block.cacheIdentifier();
break;
}
}
rb.nm = i;
// Reset row block index
rb.resetIndex();
BIFF8Row row = rb.rows[0];
AllInOneCell bCell = rb.bCell;
Cell cell;
// Cell Block(s) Cell records for all used cells (➜4.7.3)
out: for ( ; ; ) {
// Clear shared cell
bCell.clear();
short id = block.nextIdentifier();
// DBCELL record is required
if (id == ParserIdentifier.DBCELL) {
block.cacheIdentifier();
break;
}
switch (id) {
// ➜5.65 Shared string
case ParserIdentifier.LABELSST:
LabelSSTParser.get(block, bCell);
// New row
if (row.index != bCell.row) {
row = rb.getByRow(bCell.row);
}
cell = row.getCell(bCell.column);
cell.setNv(bCell.sstValue);
cell.setT(SST);
cell.xf = bCell.xf;
break;
// ➜5.71 Number
case ParserIdentifier.NUMBER:
NumberParser.get(block, bCell);
if (row.index != bCell.row) {
row = rb.getByRow(bCell.row);
}
cell = row.getCell(bCell.column);
cell.setDv(bCell.dValue);
cell.xf = bCell.xf;
break;
// ➜5.87 RK
case ParserIdentifier.RK:
RKParser.get(block, bCell);
if (row.index != bCell.row) {
row = rb.getByRow(bCell.row);
}
cell = row.getCell(bCell.column);
cell.xf = bCell.xf;
setRkValue(cell, bCell.rkValue);
break;
// ➜5.89 RSTRING
case ParserIdentifier.RSTRING:
RichStringParser.get(block, bCell);
if (row.index != bCell.row) {
row = rb.getByRow(bCell.row);
}
cell = row.getCell(bCell.column);
cell.xf = bCell.xf;
cell.setSv(bCell.sValue);
break;
// ➜5.63 LABEL
case ParserIdentifier.LABEL:
LabelParser.get(block, bCell);
if (row.index != bCell.row) {
row = rb.getByRow(bCell.row);
}
cell = row.getCell(bCell.column);
cell.xf = bCell.xf;
cell.setSv(bCell.sValue);
break;
// ➜5.7 BLANK
case ParserIdentifier.BLANK:
BlankParser.get(block, bCell);
if (row.index != bCell.row) {
row = rb.getByRow(bCell.row);
}
cell = row.getCell(bCell.column);
cell.xf = bCell.xf;
cell.setT(BLANK);
break;
// ➜5.10 BOOLERR
case ParserIdentifier.BOOLERR:
BoolErrParser.get(block, bCell);
if (row.index != bCell.row) {
row = rb.getByRow(bCell.row);
}
cell = row.getCell(bCell.column);
cell.xf = bCell.xf;
if (bCell.error == null) {
cell.setBv(bCell.bValue);
} else cell.setSv(bCell.error.getDesc());
break;
// ➜5.68 MULBLANK
case ParserIdentifier.MULBLANK:
MulBlank mulBlank = bCell.getOrNewMulBlank();
MulBlankParser.get(block, mulBlank);
if (row.index != mulBlank.row) {
row = rb.getByRow(mulBlank.row);
}
for (int j = mulBlank.fc, k = 0; j <= mulBlank.lc; j++, k++) {
cell = row.getCell(j);
cell.xf = mulBlank.xf[k];
cell.setT(BLANK);
}
break;
// ➜5.69 MULRK
case ParserIdentifier.MULRK:
MulRK mulRK = bCell.getOrNewMulRK();
MulRKParser.get(block, mulRK);
if (row.index != mulRK.row) {
row = rb.getByRow(mulRK.row);
}
for (int j = mulRK.fc, k = 0; j <= mulRK.lc; j++, k++) {
cell = row.getCell(j);
cell.xf = mulRK.xfrks[k].xf;
setRkValue(cell, mulRK.xfrks[k].rkValue);
}
break;
// ➜5.50 FORMULA
case ParserIdentifier.FORMULA:
FormulaParser.get(block, bCell);
if (row.index != bCell.row) {
row = rb.getByRow(bCell.row);
}
cell = row.getCell(bCell.column);
cell.f = true;
switch (bCell.formula.type()) {
case NUMERIC:
cell.setDv(bCell.formula.numericValue());
break ;
case BOOLEAN:
cell.setBv(bCell.formula.booleanValue());
break ;
case STRING:
cell.setSv(bCell.formula.stringValue());
break;
case EMPTY:
cell.setBlank();
break;
case ERROR:
cell.setSv(bCell.formula.errorCode().getDesc());
break;
}
break;
default:
block.cacheIdentifier();
break out;
}
}
short id = block.nextIdentifier();
if (id == ParserIdentifier.DBCELL) {
// DBCELL
DBCellParser.get(block, rb);
} else {
block.cacheIdentifier();
}
// In order to be consistent with excel07, here the line number +1
for (int j = 0; j < rb.nm; j++)
rb.rows[j].index++;
return rb;
}
private static void setRkValue(Cell cell, RKValue rkValue) {
if (rkValue.isFloat()) {
cell.setDv(rkValue.value());
} else {
cell.setNv(rkValue.value1());
}
}
}