Browse Source

refactor GetCells to return CellRangeAddressList

pull/1460/head
Tony Qu 8 months ago
parent
commit
edb5b4a9d7
  1. 27
      main/HSSF/UserModel/HSSFSheet.cs
  2. 4
      main/SS/UserModel/Sheet.cs
  3. 67
      main/SS/Util/CellRangeAddressList.cs
  4. 26
      ooxml/XSSF/Streaming/SXSSFSheet.cs
  5. 25
      ooxml/XSSF/UserModel/XSSFSheet.cs
  6. 29
      testcases/main/SS/UserModel/BaseTestSheet.cs

27
main/HSSF/UserModel/HSSFSheet.cs

@ -15,6 +15,8 @@
limitations Under the License.
==================================================================== */
using System.Collections.ObjectModel;
namespace NPOI.HSSF.UserModel
{
using System;
@ -3394,30 +3396,9 @@ namespace NPOI.HSSF.UserModel
{
return rows.Values.GetEnumerator();
}
public ICellRange<ICell> GetCells(string range)
public CellRangeAddressList GetCells(string cellranges)
{
if(string.IsNullOrWhiteSpace(range))
{
throw new ArgumentException("cell range cannot be null or empty");
}
var cells = new List<ICell>();
var rangeAddress = new RangeAddress(range);
var startCellAddress = new CellAddress(rangeAddress.FromCell);
for(int i = startCellAddress.Row; i < rangeAddress.Height; i++)
{
for(int j = startCellAddress.Column; j < rangeAddress.Width; j++)
{
var row = this.GetRow(i) ?? CreateRow(i);
var cell = row.GetCell(j) ?? row.CreateCell(j);
cells.Add(cell);
}
}
return SSCellRange<ICell>.Create(
startCellAddress.Row, startCellAddress.Column,
rangeAddress.Height, rangeAddress.Width, cells, typeof(ICell));
return CellRangeAddressList.Parse(cellranges);
}
}
}

4
main/SS/UserModel/Sheet.cs

@ -15,6 +15,8 @@
limitations under the License.
==================================================================== */
using System.Collections.ObjectModel;
namespace NPOI.SS.UserModel
{
@ -952,6 +954,6 @@ namespace NPOI.SS.UserModel
void CopyTo(IWorkbook dest, string name, bool copyStyle, bool keepFormulas);
ICellRange<ICell> GetCells(string range);
CellRangeAddressList GetCells(string cellranges);
}
}

67
main/SS/Util/CellRangeAddressList.cs

@ -1,5 +1,8 @@
using System;
using NPOI.SS.UserModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace NPOI.SS.Util
{
@ -12,11 +15,11 @@ namespace NPOI.SS.Util
/**
* List of <c>CellRangeAddress</c>es. Each structure represents a cell range
*/
private ArrayList _list;
private List<CellRangeAddress> _list;
public CellRangeAddressList()
{
_list = new ArrayList();
_list = new List<CellRangeAddress>();
}
/**
* Convenience constructor for creating a <c>CellRangeAddressList</c> with a single
@ -30,12 +33,12 @@ namespace NPOI.SS.Util
}
/**
* @param in the RecordInputstream to read the record from
* @param in the RecordInputStream to read the record from
*/
public CellRangeAddressList(RecordInputStream in1)
internal CellRangeAddressList(RecordInputStream in1)
{
int nItems = in1.ReadUShort();
_list = new ArrayList(nItems);
_list = new List<CellRangeAddress>(nItems);
for (int k = 0; k < nItems; k++)
{
@ -43,12 +46,28 @@ namespace NPOI.SS.Util
}
}
public static CellRangeAddressList Parse(string cellRanges)
{
if(string.IsNullOrWhiteSpace(cellRanges))
{
throw new ArgumentException("cell range cannot be null or empty");
}
var ranges = cellRanges.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var list = new CellRangeAddressList();
foreach(var range in ranges)
{
var ca = CellRangeAddress.ValueOf(range.Trim());
list.AddCellRangeAddress(ca);
}
return list;
}
/**
* Get the number of following ADDR structures. The number of this
* Get the number of following ADDR structures. The number of these
* structures is automatically set when reading an Excel file and/or
* increased when you manually Add a new ADDR structure . This is the reason
* there isn't a set method for this field .
*
*
* @return number of ADDR structures
*/
public int CountRanges()
@ -56,9 +75,14 @@ namespace NPOI.SS.Util
return _list.Count;
}
public int NumberOfCells()
{
return _list.Sum(cr => cr.NumberOfCells);
}
/**
* Add a cell range structure.
*
*
* @param firstRow - the upper left hand corner's row
* @param firstCol - the upper left hand corner's col
* @param lastRow - the lower right hand corner's row
@ -86,7 +110,7 @@ namespace NPOI.SS.Util
+ ") is outside allowable range (0.." + (_list.Count - 1) + ")");
}
CellRangeAddress cra = (CellRangeAddress)_list[rangeIndex];
_list.Remove(rangeIndex);
_list.Remove(_list[rangeIndex]);
return cra;
}
@ -97,24 +121,24 @@ namespace NPOI.SS.Util
{
return (CellRangeAddress)_list[index];
}
public int Serialize(int offset, byte[] data)
internal int Serialize(int offset, byte[] data)
{
int totalSize = this.Size;
Serialize(new LittleEndianByteArrayOutputStream(data, offset, totalSize));
return totalSize;
}
public void Serialize(ILittleEndianOutput out1)
internal void Serialize(ILittleEndianOutput out1)
{
int nItems = _list.Count;
out1.WriteShort(nItems);
for (int k = 0; k < nItems; k++)
{
CellRangeAddress region = (CellRangeAddress)_list[k];
region.Serialize(out1);
region?.Serialize(out1);
}
}
public int Size
internal int Size
{
get
{
@ -125,7 +149,7 @@ namespace NPOI.SS.Util
* @return the total size of for the specified number of ranges,
* including the initial 2 byte range count
*/
public static int GetEncodedSize(int numberOfRanges)
internal static int GetEncodedSize(int numberOfRanges)
{
return 2 + CellRangeAddress.GetEncodedSize(numberOfRanges);
}
@ -137,18 +161,11 @@ namespace NPOI.SS.Util
for (int k = 0; k < nItems; k++)
{
CellRangeAddress region = (CellRangeAddress)_list[k];
result.AddCellRangeAddress(region.Copy());
if (region != null)
result.AddCellRangeAddress(region.Copy());
}
return result;
}
public CellRangeAddress[] CellRangeAddresses
{
get
{
CellRangeAddress[] result =
(CellRangeAddress[])_list.ToArray(typeof(CellRangeAddress));
return result;
}
}
public CellRangeAddress[] CellRangeAddresses => _list.ToArray();
}
}

26
ooxml/XSSF/Streaming/SXSSFSheet.cs

@ -1481,31 +1481,9 @@ namespace NPOI.XSSF.Streaming
{
return ((IEnumerable<IRow>) _sh).GetEnumerator();
}
public ICellRange<ICell> GetCells(string range)
public CellRangeAddressList GetCells(string cellranges)
{
if(string.IsNullOrWhiteSpace(range))
{
throw new ArgumentException("cell range cannot be null or empty");
}
var cells = new List<ICell>();
var rangeAddress = new RangeAddress(range);
var startCellAddress = new CellAddress(rangeAddress.FromCell);
for(int i = startCellAddress.Row; i < rangeAddress.Height; i++)
{
for(int j = startCellAddress.Column; j < rangeAddress.Width; j++)
{
var row = this.GetRow(i) ?? CreateRow(i);
var cell = row.GetCell(j) ?? row.CreateCell(j);
cells.Add(cell);
}
}
return SSCellRange<ICell>.Create(
startCellAddress.Row, startCellAddress.Column,
rangeAddress.Height, rangeAddress.Width, cells, typeof(ICell));
return CellRangeAddressList.Parse(cellranges);
}
}
}

25
ooxml/XSSF/UserModel/XSSFSheet.cs

@ -6466,30 +6466,9 @@ namespace NPOI.XSSF.UserModel
#endregion
public ICellRange<ICell> GetCells(string range)
public CellRangeAddressList GetCells(string cellranges)
{
if(string.IsNullOrWhiteSpace(range))
{
throw new ArgumentException("cell range cannot be null or empty");
}
var cells = new List<ICell>();
var rangeAddress = new RangeAddress(range);
var startCellAddress = new CellAddress(rangeAddress.FromCell);
for(int i = startCellAddress.Row; i < rangeAddress.Height; i++)
{
for(int j = startCellAddress.Column; j < rangeAddress.Width; j++)
{
var row = this.GetRow(i) ?? CreateRow(i);
var cell = row.GetCell(j) ?? row.CreateCell(j);
cells.Add(cell);
}
}
return SSCellRange<ICell>.Create(
startCellAddress.Row, startCellAddress.Column,
rangeAddress.Height, rangeAddress.Width, cells, typeof(ICell));
return CellRangeAddressList.Parse(cellranges);
}
}
}

29
testcases/main/SS/UserModel/BaseTestSheet.cs

@ -1497,31 +1497,32 @@ namespace TestCases.SS.UserModel
{
var wb1 = _testDataProvider.CreateWorkbook();
var sheet = wb1.CreateSheet();
var cellRange= sheet.GetCells("A1");
Assert.AreEqual(1, cellRange.Width);
Assert.AreEqual(1, cellRange.Height);
var cellRanges= sheet.GetCells("A1");
Assert.AreEqual(1, cellRanges.CountRanges());
}
[Test]
public void TestGetCells_CellRange_WithoutSheetName()
public void TestGetCells_MultipleCellRange()
{
var wb1 = _testDataProvider.CreateWorkbook();
var sheet = wb1.CreateSheet();
var cellRange = sheet.GetCells("A1:B2");
Assert.AreEqual(2, cellRange.Width);
Assert.AreEqual(2, cellRange.Height);
Assert.AreEqual(new CellAddress(0, 0), cellRange.Cells[0][0].Address);
var cellRanges = sheet.GetCells("A1:B2, D5:F7");
Assert.AreEqual(2, cellRanges.CountRanges());
Assert.AreEqual(4+9, cellRanges.NumberOfCells());
}
[Test]
public void TestGetCells_CellRange_WithSheetName()
public void TestGetCells_SingleCellRange()
{
var wb1 = _testDataProvider.CreateWorkbook();
var sheet = wb1.CreateSheet();
var cellRange = sheet.GetCells("Sheet1!A1:C3");
Assert.AreEqual(3, cellRange.Width);
Assert.AreEqual(3, cellRange.Height);
Assert.AreEqual(new CellAddress(0, 0), cellRange.Cells[0][0].Address);
}
var cellRanges = sheet.GetCells("Sheet1!B1:D3");
Assert.AreEqual(1, cellRanges.CountRanges());
Assert.AreEqual(1, cellRanges.GetCellRangeAddress(0).FirstColumn);
Assert.AreEqual(3, cellRanges.GetCellRangeAddress(0).LastColumn);
Assert.AreEqual(0, cellRanges.GetCellRangeAddress(0).FirstRow);
Assert.AreEqual(2, cellRanges.GetCellRangeAddress(0).LastRow);
Assert.AreEqual(9, cellRanges.GetCellRangeAddress(0).NumberOfCells);
}
}
}
Loading…
Cancel
Save