namerecord.cs
来自「Excel的操作,其中可以读取及写入Excel 文件」· CS 代码 · 共 499 行
CS
499 行
using System;
using System.Collections;
using Microsoft.Fawvw.Components.NExcel.ExcelCommon;
using Microsoft.Fawvw.Components.NExcel.Biff;
namespace Microsoft.Fawvw.Components.NExcel.Read.Biff
{
/// <summary> Holds an excel name record, and the details of the cells/ranges it refers
/// to
/// </summary>
public class NameRecord:RecordData
{
/// <summary> Gets the name
///
/// </summary>
/// <returns> the strings
/// </returns>
virtual public string Name
{
get
{
return name;
}
}
/// <summary> Gets the array of ranges for this name. This method is public as it is
/// used from the writable side when copying ranges
///
/// </summary>
/// <returns> the ranges
/// </returns>
virtual public NameRange[] Ranges
{
get
{
System.Object[] o = ranges.ToArray();
NameRange[] nr = new NameRange[o.Length];
for (int i = 0; i < o.Length; i++)
{
nr[i] = (NameRange) o[i];
}
return nr;
}
}
/// <summary> Accessor for the index into the name table
///
/// </summary>
/// <returns> the 0-based index into the name table
/// </returns>
virtual internal int Index
{
get
{
return index;
}
}
/// <summary> Called when copying a sheet. Just returns the raw data
///
/// </summary>
/// <returns> the raw data
/// </returns>
virtual public sbyte[] Data
{
get
{
return getRecord().Data;
}
}
/// <summary> The logger</summary>
private static Logger logger;
/// <summary> The name</summary>
private string name;
/// <summary> The 0-based index in the name table</summary>
private int index;
/// <summary> Dummy indicators for overloading the constructor</summary>
public class Biff7
{
}
public static Biff7 biff7;
// Constants which refer to the parse tokens after the string
private const int cellReference = 0x3a;
private const int areaReference = 0x3b;
private const int subExpression = 0x29;
private const int union = 0x10;
/// <summary> A nested class to hold range information</summary>
public class NameRange
{
private void InitBlock(NameRecord enclosingInstance)
{
this.enclosingInstance = enclosingInstance;
}
private NameRecord enclosingInstance;
/// <summary> Accessor for the first column
///
/// </summary>
/// <returns> the index of the first column
/// </returns>
virtual public int FirstColumn
{
get
{
return columnFirst;
}
}
/// <summary> Accessor for the first row
///
/// </summary>
/// <returns> the index of the first row
/// </returns>
virtual public int FirstRow
{
get
{
return rowFirst;
}
}
/// <summary> Accessor for the last column
///
/// </summary>
/// <returns> the index of the last column
/// </returns>
virtual public int LastColumn
{
get
{
return columnLast;
}
}
/// <summary> Accessor for the last row
///
/// </summary>
/// <returns> the index of the last row
/// </returns>
virtual public int LastRow
{
get
{
return rowLast;
}
}
/// <summary> Accessor for the first sheet
///
/// </summary>
/// <returns> the index of the external sheet
/// </returns>
virtual public int ExternalSheet
{
get
{
return externalSheet;
}
}
public NameRecord Enclosing_Instance
{
get
{
return enclosingInstance;
}
}
/// <summary> The first column</summary>
private int columnFirst;
/// <summary> The first row</summary>
private int rowFirst;
/// <summary> The last column</summary>
private int columnLast;
/// <summary> The last row</summary>
private int rowLast;
/// <summary> The first sheet</summary>
private int externalSheet;
/// <summary> Constructor
///
/// </summary>
/// <param name="s1">the sheet
/// </param>
/// <param name="c1">the first column
/// </param>
/// <param name="r1">the first row
/// </param>
/// <param name="c2">the last column
/// </param>
/// <param name="r2">the last row
/// </param>
internal NameRange(NameRecord enclosingInstance, int s1, int c1, int r1, int c2, int r2)
{
InitBlock(enclosingInstance);
columnFirst = c1;
rowFirst = r1;
columnLast = c2;
rowLast = r2;
externalSheet = s1;
}
}
/// <summary> The ranges referenced by this name</summary>
private ArrayList ranges;
/// <summary> Constructs this object from the raw data
///
/// </summary>
/// <param name="t">the raw data
/// </param>
/// <param name="ws">the workbook settings
/// </param>
/// <param name="ind">the index in the name table
/// </param>
internal NameRecord(Record t, WorkbookSettings ws, int ind):base(t)
{
index = ind;
try
{
ranges = new ArrayList();
sbyte[] data = getRecord().Data;
int length = data[3];
name = StringHelper.getString(data, length, 15, ws);
int pos = length + 15;
if (data[pos] == cellReference)
{
int sheet = IntegerHelper.getInt(data[pos + 1], data[pos + 2]);
int row = IntegerHelper.getInt(data[pos + 3], data[pos + 4]);
int columnMask = IntegerHelper.getInt(data[pos + 5], data[pos + 6]);
int column = columnMask & 0xff;
// Check that we are not dealing with offsets
Assert.verify((columnMask & 0xc0000) == 0);
NameRange r = new NameRange(this, sheet, column, row, column, row);
ranges.Add(r);
}
else if (data[pos] == areaReference)
{
int sheet1 = 0;
// int sheet2 = 0;
int r1 = 0;
int columnMask = 0;
int c1 = 0;
int r2 = 0;
int c2 = 0;
NameRange range = null;
while (pos < data.Length)
{
sheet1 = IntegerHelper.getInt(data[pos + 1], data[pos + 2]);
r1 = IntegerHelper.getInt(data[pos + 3], data[pos + 4]);
r2 = IntegerHelper.getInt(data[pos + 5], data[pos + 6]);
columnMask = IntegerHelper.getInt(data[pos + 7], data[pos + 8]);
c1 = columnMask & 0xff;
// Check that we are not dealing with offsets
Assert.verify((columnMask & 0xc0000) == 0);
columnMask = IntegerHelper.getInt(data[pos + 9], data[pos + 10]);
c2 = columnMask & 0xff;
// Check that we are not dealing with offsets
Assert.verify((columnMask & 0xc0000) == 0);
range = new NameRange(this, sheet1, c1, r1, c2, r2);
ranges.Add(range);
pos += 11;
}
}
else if (data[pos] == subExpression)
{
int sheet1 = 0;
// int sheet2 = 0;
int r1 = 0;
int columnMask = 0;
int c1 = 0;
int r2 = 0;
int c2 = 0;
NameRange range = null;
// Consume unnecessary parsed tokens
if (pos < data.Length && data[pos] != cellReference && data[pos] != areaReference)
{
if (data[pos] == subExpression)
{
pos += 3;
}
else if (data[pos] == union)
{
pos += 1;
}
}
while (pos < data.Length)
{
sheet1 = IntegerHelper.getInt(data[pos + 1], data[pos + 2]);
r1 = IntegerHelper.getInt(data[pos + 3], data[pos + 4]);
r2 = IntegerHelper.getInt(data[pos + 5], data[pos + 6]);
columnMask = IntegerHelper.getInt(data[pos + 7], data[pos + 8]);
c1 = columnMask & 0xff;
// Check that we are not dealing with offsets
Assert.verify((columnMask & 0xc0000) == 0);
columnMask = IntegerHelper.getInt(data[pos + 9], data[pos + 10]);
c2 = columnMask & 0xff;
// Check that we are not dealing with offsets
Assert.verify((columnMask & 0xc0000) == 0);
range = new NameRange(this, sheet1, c1, r1, c2, r2);
ranges.Add(range);
pos += 11;
// Consume unnecessary parsed tokens
if (pos < data.Length && data[pos] != cellReference && data[pos] != areaReference)
{
if (data[pos] == subExpression)
{
pos += 3;
}
else if (data[pos] == union)
{
pos += 1;
}
}
}
}
}
catch (System.Exception t1)
{
// Generate a warning
// Names are really a nice to have, and we don't want to halt the
// reading process for functionality that probably won't be used
logger.warn("Cannot read name");
name = "ERROR";
}
}
/// <summary> Constructs this object from the raw data
///
/// </summary>
/// <param name="t">the raw data
/// </param>
/// <param name="ws">the workbook settings
/// </param>
/// <param name="ind">the index in the name table
/// </param>
/// <param name="dummy">dummy parameter to indicate a biff7 workbook
/// </param>
internal NameRecord(Record t, WorkbookSettings ws, int ind, Biff7 dummy):base(t)
{
index = ind;
try
{
ranges = new ArrayList();
sbyte[] data = getRecord().Data;
int length = data[3];
name = StringHelper.getString(data, length, 14, ws);
int pos = length + 14;
if (pos >= data.Length)
{
// There appears to be nothing after the name, so return
return ;
}
if (data[pos] == cellReference)
{
int sheet = IntegerHelper.getInt(data[pos + 11], data[pos + 12]);
int row = IntegerHelper.getInt(data[pos + 15], data[pos + 16]);
int column = data[pos + 17];
NameRange r = new NameRange(this, sheet, column, row, column, row);
ranges.Add(r);
}
else if (data[pos] == areaReference)
{
int sheet1 = 0;
int sheet2 = 0;
int r1 = 0;
// int columnMask = 0;
int c1 = 0;
int r2 = 0;
int c2 = 0;
NameRange range = null;
while (pos < data.Length)
{
sheet1 = IntegerHelper.getInt(data[pos + 11], data[pos + 12]);
sheet2 = IntegerHelper.getInt(data[pos + 13], data[pos + 14]);
r1 = IntegerHelper.getInt(data[pos + 15], data[pos + 16]);
r2 = IntegerHelper.getInt(data[pos + 17], data[pos + 18]);
c1 = data[pos + 19];
c2 = data[pos + 20];
range = new NameRange(this, sheet1, c1, r1, c2, r2);
ranges.Add(range);
pos += 21;
}
}
else if (data[pos] == subExpression)
{
int sheet1 = 0;
int sheet2 = 0;
int r1 = 0;
// int columnMask = 0;
int c1 = 0;
int r2 = 0;
int c2 = 0;
NameRange range = null;
// Consume unnecessary parsed tokens
if (pos < data.Length && data[pos] != cellReference && data[pos] != areaReference)
{
if (data[pos] == subExpression)
{
pos += 3;
}
else if (data[pos] == union)
{
pos += 1;
}
}
while (pos < data.Length)
{
sheet1 = IntegerHelper.getInt(data[pos + 11], data[pos + 12]);
sheet2 = IntegerHelper.getInt(data[pos + 13], data[pos + 14]);
r1 = IntegerHelper.getInt(data[pos + 15], data[pos + 16]);
r2 = IntegerHelper.getInt(data[pos + 17], data[pos + 18]);
c1 = data[pos + 19];
c2 = data[pos + 20];
range = new NameRange(this, sheet1, c1, r1, c2, r2);
ranges.Add(range);
pos += 21;
// Consume unnecessary parsed tokens
if (pos < data.Length && data[pos] != cellReference && data[pos] != areaReference)
{
if (data[pos] == subExpression)
{
pos += 3;
}
else if (data[pos] == union)
{
pos += 1;
}
}
}
}
}
catch (System.Exception t1)
{
// Generate a warning
// Names are really a nice to have, and we don't want to halt the
// reading process for functionality that probably won't be used
logger.warn("Cannot read name.");
name = "ERROR";
}
}
static NameRecord()
{
logger = Logger.getLogger(typeof(NameRecord));
biff7 = new Biff7();
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?