Files
HRMS/hrmsEjb/jxl/read/biff/WorkbookParser.java
2025-07-28 13:56:49 +05:30

521 lines
16 KiB
Java

package jxl.read.biff;
import common.Assert;
import common.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import jxl.Cell;
import jxl.Range;
import jxl.Sheet;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.biff.CellReferenceHelper;
import jxl.biff.DisplayFormat;
import jxl.biff.FontRecord;
import jxl.biff.Fonts;
import jxl.biff.FormatRecord;
import jxl.biff.FormattingRecords;
import jxl.biff.NumFormatRecordsException;
import jxl.biff.PaletteRecord;
import jxl.biff.RangeImpl;
import jxl.biff.Type;
import jxl.biff.WorkbookMethods;
import jxl.biff.XFRecord;
import jxl.biff.drawing.DrawingGroup;
import jxl.biff.drawing.MsoDrawingGroupRecord;
import jxl.biff.drawing.Origin;
import jxl.biff.formula.ExternalSheet;
public class WorkbookParser extends Workbook implements ExternalSheet, WorkbookMethods {
private static Logger logger = Logger.getLogger(WorkbookParser.class);
private File excelFile;
private int bofs;
private boolean nineteenFour;
private SSTRecord sharedStrings;
private ArrayList boundsheets;
private FormattingRecords formattingRecords;
private Fonts fonts;
private ArrayList sheets;
private SheetImpl lastSheet;
private int lastSheetIndex;
private HashMap namedRecords;
private ArrayList nameTable;
private ExternalSheetRecord externSheet;
private ArrayList supbooks;
private BOFRecord workbookBof;
private MsoDrawingGroupRecord msoDrawingGroup;
private ButtonPropertySetRecord buttonPropertySet;
private boolean wbProtected;
private boolean containsMacros;
private WorkbookSettings settings;
private DrawingGroup drawingGroup;
private CountryRecord countryRecord;
public WorkbookParser(File f, WorkbookSettings s) {
this.excelFile = f;
this.boundsheets = new ArrayList(10);
this.fonts = new Fonts();
this.formattingRecords = new FormattingRecords(this.fonts);
this.sheets = new ArrayList(10);
this.supbooks = new ArrayList(10);
this.namedRecords = new HashMap();
this.lastSheetIndex = -1;
this.wbProtected = false;
this.containsMacros = false;
this.settings = s;
}
public Sheet[] getSheets() {
Sheet[] sheetArray = new Sheet[getNumberOfSheets()];
return (Sheet[])this.sheets.toArray((Object[])sheetArray);
}
public Sheet getReadSheet(int index) {
return getSheet(index);
}
public Sheet getSheet(int index) {
if (this.lastSheet != null && this.lastSheetIndex == index)
return this.lastSheet;
if (this.lastSheet != null) {
this.lastSheet.clear();
if (!this.settings.getGCDisabled())
System.gc();
}
this.lastSheet = this.sheets.get(index);
this.lastSheetIndex = index;
this.lastSheet.readSheet();
return this.lastSheet;
}
public Sheet getSheet(String name) {
int pos = 0;
boolean found = false;
Iterator i = this.boundsheets.iterator();
BoundsheetRecord br = null;
while (i.hasNext() && !found) {
br = i.next();
if (br.getName().equals(name)) {
found = true;
continue;
}
pos++;
}
return found ? getSheet(pos) : null;
}
public String[] getSheetNames() {
String[] names = new String[this.boundsheets.size()];
BoundsheetRecord br = null;
for (int i = 0; i < names.length; i++) {
br = this.boundsheets.get(i);
names[i] = br.getName();
}
return names;
}
public int getExternalSheetIndex(int index) {
if (this.workbookBof.isBiff7())
return index;
Assert.verify((this.externSheet != null));
int firstTab = this.externSheet.getFirstTabIndex(index);
return firstTab;
}
public int getLastExternalSheetIndex(int index) {
if (this.workbookBof.isBiff7())
return index;
Assert.verify((this.externSheet != null));
int lastTab = this.externSheet.getLastTabIndex(index);
return lastTab;
}
public String getExternalSheetName(int index) {
if (this.workbookBof.isBiff7()) {
BoundsheetRecord br = this.boundsheets.get(index);
return br.getName();
}
int supbookIndex = this.externSheet.getSupbookIndex(index);
SupbookRecord sr = this.supbooks.get(supbookIndex);
int firstTab = this.externSheet.getFirstTabIndex(index);
if (sr.getType() == SupbookRecord.INTERNAL) {
BoundsheetRecord br = this.boundsheets.get(firstTab);
return br.getName();
}
if (sr.getType() == SupbookRecord.EXTERNAL) {
StringBuffer sb = new StringBuffer();
sb.append('[');
sb.append(sr.getFileName());
sb.append(']');
sb.append(sr.getSheetName(firstTab));
return sb.toString();
}
return "[UNKNOWN]";
}
public String getLastExternalSheetName(int index) {
if (this.workbookBof.isBiff7()) {
BoundsheetRecord br = this.boundsheets.get(index);
return br.getName();
}
int supbookIndex = this.externSheet.getSupbookIndex(index);
SupbookRecord sr = this.supbooks.get(supbookIndex);
int lastTab = this.externSheet.getLastTabIndex(index);
if (sr.getType() == SupbookRecord.INTERNAL) {
BoundsheetRecord br = this.boundsheets.get(lastTab);
return br.getName();
}
if (sr.getType() == SupbookRecord.EXTERNAL) {
StringBuffer sb = new StringBuffer();
sb.append('[');
sb.append(sr.getFileName());
sb.append(']');
sb.append(sr.getSheetName(lastTab));
return sb.toString();
}
return "[UNKNOWN]";
}
public int getNumberOfSheets() {
return this.sheets.size();
}
public void close() {
if (this.lastSheet != null)
this.lastSheet.clear();
this.excelFile.clear();
if (!this.settings.getGCDisabled())
System.gc();
}
final void addSheet(Sheet s) {
this.sheets.add(s);
}
protected void parse() throws BiffException, PasswordException {
Record r = null;
BOFRecord bof = new BOFRecord(this.excelFile.next());
this.workbookBof = bof;
this.bofs++;
if (!bof.isBiff8() && !bof.isBiff7())
throw new BiffException(BiffException.unrecognizedBiffVersion);
if (!bof.isWorkbookGlobals())
throw new BiffException(BiffException.expectedGlobals);
ArrayList continueRecords = new ArrayList();
this.nameTable = new ArrayList();
while (this.bofs == 1) {
r = this.excelFile.next();
if (r.getType() == Type.SST) {
continueRecords.clear();
Record nextrec = this.excelFile.peek();
while (nextrec.getType() == Type.CONTINUE) {
continueRecords.add(this.excelFile.next());
nextrec = this.excelFile.peek();
}
Record[] records = new Record[continueRecords.size()];
records = continueRecords.<Record>toArray(records);
this.sharedStrings = new SSTRecord(r, records, this.settings);
continue;
}
if (r.getType() == Type.FILEPASS)
throw new PasswordException();
if (r.getType() == Type.NAME) {
NameRecord nr = null;
if (bof.isBiff8()) {
nr = new NameRecord(r, this.settings, this.namedRecords.size());
} else {
nr = new NameRecord(r, this.settings, this.namedRecords.size(), NameRecord.biff7);
}
this.namedRecords.put(nr.getName(), nr);
this.nameTable.add(nr);
continue;
}
if (r.getType() == Type.FONT) {
FontRecord fr = null;
if (bof.isBiff8()) {
fr = new FontRecord(r, this.settings);
} else {
fr = new FontRecord(r, this.settings, FontRecord.biff7);
}
this.fonts.addFont(fr);
continue;
}
if (r.getType() == Type.PALETTE) {
PaletteRecord palette = new PaletteRecord(r);
this.formattingRecords.setPalette(palette);
continue;
}
if (r.getType() == Type.NINETEENFOUR) {
NineteenFourRecord nr = new NineteenFourRecord(r);
this.nineteenFour = nr.is1904();
continue;
}
if (r.getType() == Type.FORMAT) {
FormatRecord fr = null;
if (bof.isBiff8()) {
fr = new FormatRecord(r, this.settings, FormatRecord.biff8);
} else {
fr = new FormatRecord(r, this.settings, FormatRecord.biff7);
}
try {
this.formattingRecords.addFormat((DisplayFormat)fr);
} catch (NumFormatRecordsException e) {
e.printStackTrace();
Assert.verify(false, e.getMessage());
}
continue;
}
if (r.getType() == Type.XF) {
XFRecord xfr = null;
if (bof.isBiff8()) {
xfr = new XFRecord(r, this.settings, XFRecord.biff8);
} else {
xfr = new XFRecord(r, this.settings, XFRecord.biff7);
}
try {
this.formattingRecords.addStyle(xfr);
} catch (NumFormatRecordsException e) {
Assert.verify(false, e.getMessage());
}
continue;
}
if (r.getType() == Type.BOUNDSHEET) {
BoundsheetRecord br = null;
if (bof.isBiff8()) {
br = new BoundsheetRecord(r);
} else {
br = new BoundsheetRecord(r, BoundsheetRecord.biff7);
}
if (br.isSheet()) {
this.boundsheets.add(br);
continue;
}
if (br.isChart() && !this.settings.getDrawingsDisabled())
this.boundsheets.add(br);
continue;
}
if (r.getType() == Type.EXTERNSHEET) {
if (bof.isBiff8()) {
this.externSheet = new ExternalSheetRecord(r, this.settings);
continue;
}
this.externSheet = new ExternalSheetRecord(r, this.settings, ExternalSheetRecord.biff7);
continue;
}
if (r.getType() == Type.CODEPAGE) {
CodepageRecord cr = new CodepageRecord(r);
this.settings.setCharacterSet(cr.getCharacterSet());
continue;
}
if (r.getType() == Type.SUPBOOK) {
Record nextrec = this.excelFile.peek();
while (nextrec.getType() == Type.CONTINUE) {
r.addContinueRecord(this.excelFile.next());
nextrec = this.excelFile.peek();
}
SupbookRecord sr = new SupbookRecord(r, this.settings);
this.supbooks.add(sr);
continue;
}
if (r.getType() == Type.PROTECT) {
ProtectRecord pr = new ProtectRecord(r);
this.wbProtected = pr.isProtected();
continue;
}
if (r.getType() == Type.OBJPROJ) {
this.containsMacros = true;
continue;
}
if (r.getType() == Type.COUNTRY) {
this.countryRecord = new CountryRecord(r);
continue;
}
if (r.getType() == Type.MSODRAWINGGROUP) {
if (!this.settings.getDrawingsDisabled()) {
this.msoDrawingGroup = new MsoDrawingGroupRecord(r);
if (this.drawingGroup == null)
this.drawingGroup = new DrawingGroup(Origin.READ);
this.drawingGroup.add(this.msoDrawingGroup);
Record nextrec = this.excelFile.peek();
while (nextrec.getType() == Type.CONTINUE) {
this.drawingGroup.add(this.excelFile.next());
nextrec = this.excelFile.peek();
}
}
continue;
}
if (r.getType() == Type.BUTTONPROPERTYSET) {
this.buttonPropertySet = new ButtonPropertySetRecord(r);
continue;
}
if (r.getType() == Type.EOF)
this.bofs--;
}
bof = null;
if (this.excelFile.hasNext()) {
r = this.excelFile.next();
if (r.getType() == Type.BOF)
bof = new BOFRecord(r);
}
while (bof != null && getNumberOfSheets() < this.boundsheets.size()) {
if (!bof.isBiff8() && !bof.isBiff7())
throw new BiffException(BiffException.unrecognizedBiffVersion);
if (bof.isWorksheet()) {
SheetImpl s = new SheetImpl(this.excelFile, this.sharedStrings, this.formattingRecords, bof, this.workbookBof, this.nineteenFour, this);
BoundsheetRecord br = this.boundsheets.get(getNumberOfSheets());
s.setName(br.getName());
s.setHidden(br.isHidden());
addSheet(s);
} else if (bof.isChart()) {
SheetImpl s = new SheetImpl(this.excelFile, this.sharedStrings, this.formattingRecords, bof, this.workbookBof, this.nineteenFour, this);
BoundsheetRecord br = this.boundsheets.get(getNumberOfSheets());
s.setName(br.getName());
s.setHidden(br.isHidden());
addSheet(s);
} else {
logger.warn("BOF is unrecognized");
while (this.excelFile.hasNext() && r.getType() != Type.EOF)
r = this.excelFile.next();
}
bof = null;
if (this.excelFile.hasNext()) {
r = this.excelFile.next();
if (r.getType() == Type.BOF)
bof = new BOFRecord(r);
}
}
}
public FormattingRecords getFormattingRecords() {
return this.formattingRecords;
}
public ExternalSheetRecord getExternalSheetRecord() {
return this.externSheet;
}
public MsoDrawingGroupRecord getMsoDrawingGroupRecord() {
return this.msoDrawingGroup;
}
public SupbookRecord[] getSupbookRecords() {
SupbookRecord[] sr = new SupbookRecord[this.supbooks.size()];
return (SupbookRecord[])this.supbooks.toArray((Object[])sr);
}
public NameRecord[] getNameRecords() {
NameRecord[] na = new NameRecord[this.nameTable.size()];
return (NameRecord[])this.nameTable.toArray((Object[])na);
}
public Fonts getFonts() {
return this.fonts;
}
public Cell getCell(String loc) {
Sheet s = getSheet(CellReferenceHelper.getSheet(loc));
return s.getCell(loc);
}
public Cell findCellByName(String name) {
NameRecord nr = (NameRecord)this.namedRecords.get(name);
if (nr == null)
return null;
NameRecord.NameRange[] ranges = nr.getRanges();
Sheet s = getSheet(ranges[0].getExternalSheet());
Cell cell = s.getCell(ranges[0].getFirstColumn(), ranges[0].getFirstRow());
return cell;
}
public Range[] findByName(String name) {
NameRecord nr = (NameRecord)this.namedRecords.get(name);
if (nr == null)
return null;
NameRecord.NameRange[] ranges = nr.getRanges();
Range[] cellRanges = new Range[ranges.length];
for (int i = 0; i < ranges.length; i++)
cellRanges[i] = (Range)new RangeImpl(this, getExternalSheetIndex(ranges[i].getExternalSheet()), ranges[i].getFirstColumn(), ranges[i].getFirstRow(), getLastExternalSheetIndex(ranges[i].getExternalSheet()), ranges[i].getLastColumn(), ranges[i].getLastRow());
return cellRanges;
}
public String[] getRangeNames() {
Object[] keys = this.namedRecords.keySet().toArray();
String[] names = new String[keys.length];
System.arraycopy(keys, 0, names, 0, keys.length);
return names;
}
public BOFRecord getWorkbookBof() {
return this.workbookBof;
}
public boolean isProtected() {
return this.wbProtected;
}
public WorkbookSettings getSettings() {
return this.settings;
}
public int getExternalSheetIndex(String sheetName) {
return 0;
}
public int getLastExternalSheetIndex(String sheetName) {
return 0;
}
public String getName(int index) {
Assert.verify((index >= 0 && index < this.nameTable.size()));
return ((NameRecord)this.nameTable.get(index)).getName();
}
public int getNameIndex(String name) {
NameRecord nr = (NameRecord)this.namedRecords.get(name);
return (nr != null) ? nr.getIndex() : 0;
}
public DrawingGroup getDrawingGroup() {
return this.drawingGroup;
}
public CompoundFile getCompoundFile() {
return this.excelFile.getCompoundFile();
}
public boolean containsMacros() {
return this.containsMacros;
}
public ButtonPropertySetRecord getButtonPropertySet() {
return this.buttonPropertySet;
}
public CountryRecord getCountryRecord() {
return this.countryRecord;
}
}