org.ttzero.excel.entity.e3.BOFParser 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.entity.e3;
import org.ttzero.excel.entity.e3.enums.BIFFVerEnum;
import org.ttzero.excel.entity.e3.enums.StreamTypeEnum;
import org.ttzero.excel.reader.ExcelReadException;
/**
* 5.8 BOF – Beginning of File
*
* The BOF record is the first record of any kind of stream or sub-stream:
*
* - The Worksheet Stream (➜4.1.1) and the Chart Stream (➜7.1.1)
* - All sub-streams in the Workbook Stream (the Sheet Sub-stream
* and the Workbook Globals Sub-stream, ➜4.1.2,
* and the Chart Sub-stream, ➜7.1.2)
* - The Workspace Stream
*
* A BOF record will never be encrypted, regardless of
* its type and position in the stream.
*
* If a BIFF8 version of Excel (Excel 8.0 and newer) writes
* a BIFF5 workbook, it writes a wrong BIFF version in BOF
* records of the Sheet Sub-streams. Only the leading BOF
* record of the Workbook Globals Sub-stream contains the
* correct value and should be used to determine the BIFF
* version for the entire stream.
*
* @author guanquan.wang at 2019-01-31 15:19
*/
public class BOFParser {
public static BOF get(Block block) {
// Mark the ready flag
block.ready();
// BIFF version (always 0600H for BIFF8)
short version = block.nextShort();
if (version < 0x0600) {
String v;
switch (version) {
case 0x0500:
case 0x0000:
v = "BIFF5"; break;
case 0x0400: v = "BIFF4"; break;
case 0x0300: v = "BIFF3"; break;
case 0x0200: v = "BIFF2"; break;
default:
v = "Unknown";
}
throw new ExcelReadException("Only support BIFF8. Current version is " + v);
}
// Type of the following data
short type = block.nextShort();
StreamTypeEnum streamType = StreamTypeEnum.of(type);
if (streamType == null) {
throw new ExcelReadException("Unknown stream type." + type);
}
/*
Various external tools write non-standard BOF records with the record
identifier 0809H (determining a BIFF5-BIFF8 BOF record), but with a
different BIFF version field. In this case, the record identifier is ignored,
and only the version field is used to set the BIFF version of the workbook.
*/
// // Build identifier, must not be 0
// short identifier = block.nextShort();
// if (identifier == 0) {
// throw new ExcelReadException("Build identifier must not be zero.");
// }
// // Build year, must not be 0
// short year = block.nextShort();
// if (year == 0) {
// throw new ExcelReadException("Build year must not be zero.");
// }
// // File history flags
// int history = block.nextInt();
// // Lowest Excel version that can read all records in this file
// int supportLowestVersion = block.nextInt();
//
// BIFFVerEnum lowVer = null;
// for (BIFFVerEnum ver : BIFFVerEnum.values()) {
// if (ver.getValue() > supportLowestVersion) {
// lowVer = ver;
// break;
// }
// }
// Block end of read
block.commit();
BOF bof = new BOF();
bof.version = version;
bof.type = streamType;
// bof.identifier = identifier;
// bof.year = year;
// bof.supportLowestVersion = lowVer;
// bof.history = history;
return bof;
}
public static short getId() {
return ParserIdentifier.BOF;
}
public static class BOF {
short version;
StreamTypeEnum type;
short identifier;
short year;
int history;
BIFFVerEnum supportLowestVersion;
@Override
public String toString() {
return
"Version: " + version +
" Type: " + type +
" Identifier: " + identifier +
" Build year: " + year +
" History: " + history +
" SupportLowestVersion: " + supportLowestVersion;
}
}
}