diff --git a/src/ExcelDataReader.Tests/ExcelBinaryReaderTest.cs b/src/ExcelDataReader.Tests/ExcelBinaryReaderTest.cs
index ca2e345b..1531b60d 100644
--- a/src/ExcelDataReader.Tests/ExcelBinaryReaderTest.cs
+++ b/src/ExcelDataReader.Tests/ExcelBinaryReaderTest.cs
@@ -110,7 +110,7 @@ public void TestOpenOffice()
}
///
- /// Issue 11 - OpenOffice files were skipping the first row if IsFirstRowAsColumnNames = false;
+ /// Issue 11 - OpenOffice files were skipping the first row if IsFirstRowAsColumnNames = false.
///
[Test]
public void GitIssue11OpenOfficeRowCount()
@@ -170,7 +170,7 @@ public void Issue11572CodePage()
}
///
- /// Not fixed yet
+ /// Not fixed yet.
///
[Test]
public void Issue11545NoIndex()
@@ -211,7 +211,7 @@ public void Issue11636BiffStream()
/// Not fixed yet
/// The problem occurs with unseekable stream and logic related to minifat that uses seek
/// It should probably only use seek if it needs to go backwards, I think at the moment it uses seek all the time
- /// which is probably not good for performance
+ /// which is probably not good for performance.
///
[Test]
[Ignore("Not fixed yet")]
@@ -228,7 +228,7 @@ public void Issue1163911644ForwardOnlyStream()
/// Not fixed yet
/// The problem occurs with unseekable stream and logic related to minifat that uses seek
/// It should probably only use seek if it needs to go backwards, I think at the moment it uses seek all the time
- /// which is probably not good for performance
+ /// which is probably not good for performance.
///
[Test]
public void Issue12556Corrupt()
@@ -243,7 +243,7 @@ public void Issue12556Corrupt()
}
///
- /// Some spreadsheets were crashing with index out of range error (from SSRS)
+ /// Some spreadsheets were crashing with index out of range error (from SSRS).
///
[Test]
public void TestIssue11818OutOfRange()
@@ -1069,6 +1069,30 @@ public void GitIssue578()
Assert.That(values3, Is.EqualTo(new object[] { 1, 2, 3, 4 }));
}
+ [Test]
+ public void GitIssue642_ActiveSheet()
+ {
+ using var reader = OpenReader("Test_git_issue_642");
+ var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration()
+ {
+ FilterSheet = (tableReader, sheetIndex) => tableReader.IsActiveSheet
+ });
+ Assert.That(reader.ActiveSheet, Is.EqualTo(5));
+ Assert.That(dataSet.Tables[0].TableName, Is.EqualTo("List6"));
+ }
+
+ [Test]
+ public void GitIssue642_ActiveSheet_SingleWorksheet()
+ {
+ using var reader = OpenReader("Test_git_issue_642onesheet");
+ var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration()
+ {
+ FilterSheet = (tableReader, sheetIndex) => tableReader.IsActiveSheet
+ });
+ Assert.That(reader.ActiveSheet, Is.EqualTo(0));
+ Assert.That(dataSet.Tables[0].TableName, Is.EqualTo("List1"));
+ }
+
protected override IExcelDataReader OpenReader(Stream stream, ExcelReaderConfiguration configuration = null)
{
return ExcelReaderFactory.CreateBinaryReader(stream, configuration);
diff --git a/src/ExcelDataReader.Tests/ExcelCsvReaderTest.cs b/src/ExcelDataReader.Tests/ExcelCsvReaderTest.cs
index e9a52c00..b8e0b10b 100644
--- a/src/ExcelDataReader.Tests/ExcelCsvReaderTest.cs
+++ b/src/ExcelDataReader.Tests/ExcelCsvReaderTest.cs
@@ -3,7 +3,7 @@
namespace ExcelDataReader.Tests;
///
-/// Most CSV test data came from csv-spectrum: https://github.com/maxogden/csv-spectrum
+/// Most CSV test data came from csv-spectrum: https://github.com/maxogden/csv-spectrum.
///
public class ExcelCsvReaderTest
{
@@ -467,4 +467,16 @@ public void GitIssue463()
Assert.That(row4, Is.EqualTo(new object[] { "Test3", "IJK", "ZZ", "10,143.27", "0.00" }));
});
}
+
+ [Test]
+ public void GitIssue642_ActiveSheet()
+ {
+ using var reader = ExcelReaderFactory.CreateCsvReader(Configuration.GetTestWorkbook("csv\\MOCK_DATA.csv"));
+ var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration()
+ {
+ FilterSheet = (tableReader, sheetIndex) => tableReader.IsActiveSheet
+ });
+ Assert.That(reader.ActiveSheet, Is.EqualTo(0));
+ Assert.That(dataSet.Tables.Count, Is.EqualTo(1));
+ }
}
diff --git a/src/ExcelDataReader.Tests/ExcelOpenXmlBinaryReaderTest.cs b/src/ExcelDataReader.Tests/ExcelOpenXmlBinaryReaderTest.cs
index bbe3bb24..06e15562 100644
--- a/src/ExcelDataReader.Tests/ExcelOpenXmlBinaryReaderTest.cs
+++ b/src/ExcelDataReader.Tests/ExcelOpenXmlBinaryReaderTest.cs
@@ -14,6 +14,30 @@ public void GitIssue635()
Assert.That(dataSet.Tables[0].Rows[0].ItemArray, Is.EqualTo(new[] { "A", "B", "C", "D", "E", "F" }));
}
+ [Test]
+ public void GitIssue642_ActiveSheet()
+ {
+ using var reader = OpenReader("Test_git_issue_642");
+ var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration()
+ {
+ FilterSheet = (tableReader, sheetIndex) => tableReader.IsActiveSheet
+ });
+ Assert.That(reader.ActiveSheet, Is.EqualTo(5));
+ Assert.That(dataSet.Tables[0].TableName, Is.EqualTo("List6"));
+ }
+
+ [Test]
+ public void GitIssue642_ActiveSheet_SingleWorksheet()
+ {
+ using var reader = OpenReader("Test_git_issue_642onesheet");
+ var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration()
+ {
+ FilterSheet = (tableReader, sheetIndex) => tableReader.IsActiveSheet
+ });
+ Assert.That(reader.ActiveSheet, Is.EqualTo(0));
+ Assert.That(dataSet.Tables[0].TableName, Is.EqualTo("List1"));
+ }
+
///
protected override Stream OpenStream(string name)
{
diff --git a/src/ExcelDataReader.Tests/ExcelOpenXmlReaderTest.cs b/src/ExcelDataReader.Tests/ExcelOpenXmlReaderTest.cs
index 99f37384..93ee0df9 100644
--- a/src/ExcelDataReader.Tests/ExcelOpenXmlReaderTest.cs
+++ b/src/ExcelDataReader.Tests/ExcelOpenXmlReaderTest.cs
@@ -458,6 +458,30 @@ public void GitIssue518MultipleHeaderRows()
}
}
+ [Test]
+ public void GitIssue642_ActiveSheet()
+ {
+ using var reader = OpenReader("Test_git_issue_642");
+ var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration()
+ {
+ FilterSheet = (tableReader, sheetIndex) => tableReader.IsActiveSheet
+ });
+ Assert.That(reader.ActiveSheet, Is.EqualTo(5));
+ Assert.That(dataSet.Tables[0].TableName, Is.EqualTo("List6"));
+ }
+
+ [Test]
+ public void GitIssue642_ActiveSheet_SingleWorksheet()
+ {
+ using var reader = OpenReader("Test_git_issue_642onesheet");
+ var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration()
+ {
+ FilterSheet = (tableReader, sheetIndex) => tableReader.IsActiveSheet
+ });
+ Assert.That(reader.ActiveSheet, Is.EqualTo(0));
+ Assert.That(dataSet.Tables[0].TableName, Is.EqualTo("List1"));
+ }
+
protected override IExcelDataReader OpenReader(Stream stream, ExcelReaderConfiguration configuration = null)
=> ExcelReaderFactory.CreateOpenXmlReader(stream, configuration);
diff --git a/src/ExcelDataReader.Tests/ExcelTestBase.cs b/src/ExcelDataReader.Tests/ExcelTestBase.cs
index 30671310..0a12df18 100644
--- a/src/ExcelDataReader.Tests/ExcelTestBase.cs
+++ b/src/ExcelDataReader.Tests/ExcelTestBase.cs
@@ -49,7 +49,7 @@ public void Issue11773ExponentialCommas()
}
///
- /// Makes sure that we can read data from the first row of last sheet
+ /// Makes sure that we can read data from the first row of last sheet.
///
[Test]
public void Issue12271NextResultSet()
diff --git a/src/ExcelDataReader/Core/BinaryFormat/XlsWorkbook.cs b/src/ExcelDataReader/Core/BinaryFormat/XlsWorkbook.cs
index 9fb5b70d..8e578bdc 100644
--- a/src/ExcelDataReader/Core/BinaryFormat/XlsWorkbook.cs
+++ b/src/ExcelDataReader/Core/BinaryFormat/XlsWorkbook.cs
@@ -77,6 +77,8 @@ internal XlsWorkbook(Stream stream, string password, Encoding fallbackEncoding)
public int ResultsCount => Sheets?.Count ?? -1;
+ public int ActiveSheet { get; private set; }
+
public static bool IsRawBiffStream(byte[] bytes)
{
if (bytes.Length < 8)
@@ -203,6 +205,10 @@ private void ReadWorkbookGlobals(XlsBiffStream biffStream)
ExtSST = rec;
break;
+ case XlsBiffRecord _ when rec.Id == BIFFRECORDTYPE.WINDOW1:
+ ActiveSheet = rec.ReadInt16(10);
+ break;
+
// case BIFFRECORDTYPE.PROTECT:
// case BIFFRECORDTYPE.PROT4REVPASSWORD:
// IsProtected
diff --git a/src/ExcelDataReader/Core/BinaryFormat/XlsWorksheet.cs b/src/ExcelDataReader/Core/BinaryFormat/XlsWorksheet.cs
index 38fe95bc..c3239d2f 100644
--- a/src/ExcelDataReader/Core/BinaryFormat/XlsWorksheet.cs
+++ b/src/ExcelDataReader/Core/BinaryFormat/XlsWorksheet.cs
@@ -42,6 +42,11 @@ public XlsWorksheet(XlsWorkbook workbook, XlsBiffBoundSheet refSheet, Stream str
///
public string VisibleState { get; }
+ ///
+ /// Gets a value indicating whether the sheet is active.
+ ///
+ public bool IsActiveSheet { get; }
+
public HeaderFooter HeaderFooter { get; private set; }
public CellRange[] MergeCells { get; private set; }
diff --git a/src/ExcelDataReader/Core/CsvFormat/CsvWorkbook.cs b/src/ExcelDataReader/Core/CsvFormat/CsvWorkbook.cs
index aeb24a95..f1af684d 100644
--- a/src/ExcelDataReader/Core/CsvFormat/CsvWorkbook.cs
+++ b/src/ExcelDataReader/Core/CsvFormat/CsvWorkbook.cs
@@ -7,6 +7,8 @@ internal sealed class CsvWorkbook(Stream stream, Encoding encoding, char[] autod
{
public int ResultsCount => 1;
+ public int ActiveSheet => 0;
+
public Stream Stream { get; } = stream;
public Encoding Encoding { get; } = encoding;
diff --git a/src/ExcelDataReader/Core/CsvFormat/CsvWorksheet.cs b/src/ExcelDataReader/Core/CsvFormat/CsvWorksheet.cs
index a73be669..65141453 100644
--- a/src/ExcelDataReader/Core/CsvFormat/CsvWorksheet.cs
+++ b/src/ExcelDataReader/Core/CsvFormat/CsvWorksheet.cs
@@ -34,6 +34,10 @@ public CsvWorksheet(Stream stream, Encoding fallbackEncoding, char[] autodetectS
}
}
+ public static int ActiveSheet => 0;
+
+ public static bool IsActiveSheet => true;
+
public string Name => string.Empty;
public string CodeName => null;
diff --git a/src/ExcelDataReader/Core/IWorkbook.cs b/src/ExcelDataReader/Core/IWorkbook.cs
index 251a213d..1ed4f34b 100644
--- a/src/ExcelDataReader/Core/IWorkbook.cs
+++ b/src/ExcelDataReader/Core/IWorkbook.cs
@@ -11,6 +11,8 @@ internal interface IWorkbook
{
int ResultsCount { get; }
+ int ActiveSheet { get; }
+
IEnumerable ReadWorksheets();
NumberFormatString GetNumberFormatString(int index);
diff --git a/src/ExcelDataReader/Core/OpenXmlFormat/BinaryFormat/BiffWorkbookReader.cs b/src/ExcelDataReader/Core/OpenXmlFormat/BinaryFormat/BiffWorkbookReader.cs
index eea1153d..857f82a1 100644
--- a/src/ExcelDataReader/Core/OpenXmlFormat/BinaryFormat/BiffWorkbookReader.cs
+++ b/src/ExcelDataReader/Core/OpenXmlFormat/BinaryFormat/BiffWorkbookReader.cs
@@ -8,7 +8,8 @@ internal sealed class BiffWorkbookReader(Stream stream, Dictionary _worksheetRels = worksheetRels;
private enum SheetVisibility : byte
@@ -42,6 +43,11 @@ protected override Record ReadOverride(byte[] buffer, uint recordId, uint record
string name = GetString(buffer, offset + 4, nameLength);
return new SheetRecord(name, id, rid, state, rid != null && _worksheetRels.TryGetValue(rid, out var path) ? path : null);
+
+ case BrtBookView:
+ int activeSheet = (int)GetDWord(buffer, 24);
+ return new WorkbookActRecord(activeSheet);
+
default:
return Record.Default;
}
diff --git a/src/ExcelDataReader/Core/OpenXmlFormat/Records/WorkbookActRecord.cs b/src/ExcelDataReader/Core/OpenXmlFormat/Records/WorkbookActRecord.cs
new file mode 100644
index 00000000..f5723504
--- /dev/null
+++ b/src/ExcelDataReader/Core/OpenXmlFormat/Records/WorkbookActRecord.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ExcelDataReader.Core.OpenXmlFormat.Records;
+
+internal sealed class WorkbookActRecord : Record
+{
+ public WorkbookActRecord(int activeSheet)
+ {
+ this.ActiveSheet = activeSheet;
+ }
+
+ public int ActiveSheet { get; }
+}
diff --git a/src/ExcelDataReader/Core/OpenXmlFormat/XlsxWorkbook.cs b/src/ExcelDataReader/Core/OpenXmlFormat/XlsxWorkbook.cs
index 57ae651b..a96f5072 100644
--- a/src/ExcelDataReader/Core/OpenXmlFormat/XlsxWorkbook.cs
+++ b/src/ExcelDataReader/Core/OpenXmlFormat/XlsxWorkbook.cs
@@ -22,6 +22,8 @@ public XlsxWorkbook(ZipWorker zipWorker)
public int ResultsCount => Sheets?.Count ?? -1;
+ public int ActiveSheet { get; private set; }
+
public IEnumerable ReadWorksheets()
{
foreach (var sheet in Sheets)
@@ -45,6 +47,9 @@ private void ReadWorkbook()
case SheetRecord sheet:
Sheets.Add(sheet);
break;
+ case WorkbookActRecord activeSheet:
+ ActiveSheet = activeSheet.ActiveSheet;
+ break;
}
}
}
diff --git a/src/ExcelDataReader/Core/OpenXmlFormat/XlsxWorksheet.cs b/src/ExcelDataReader/Core/OpenXmlFormat/XlsxWorksheet.cs
index 35455f69..dc794872 100644
--- a/src/ExcelDataReader/Core/OpenXmlFormat/XlsxWorksheet.cs
+++ b/src/ExcelDataReader/Core/OpenXmlFormat/XlsxWorksheet.cs
@@ -91,6 +91,8 @@ public XlsxWorksheet(ZipWorker document, XlsxWorkbook workbook, SheetRecord refS
public string VisibleState { get; }
+ public bool IsActiveSheet { get; }
+
public HeaderFooter HeaderFooter { get; }
public double DefaultRowHeight { get; }
diff --git a/src/ExcelDataReader/Core/OpenXmlFormat/XmlFormat/XmlWorkbookReader.cs b/src/ExcelDataReader/Core/OpenXmlFormat/XmlFormat/XmlWorkbookReader.cs
index 308b41cd..c10a4ff4 100644
--- a/src/ExcelDataReader/Core/OpenXmlFormat/XmlFormat/XmlWorkbookReader.cs
+++ b/src/ExcelDataReader/Core/OpenXmlFormat/XmlFormat/XmlWorkbookReader.cs
@@ -66,6 +66,28 @@ protected override IEnumerable ReadOverride()
}
}
}
+ else if (Reader.IsStartElement("bookViews", ProperNamespaces.NsSpreadsheetMl))
+ {
+ if (!XmlReaderHelper.ReadFirstContent(Reader))
+ {
+ continue;
+ }
+
+ while (!Reader.EOF)
+ {
+ if (Reader.IsStartElement("workbookView", ProperNamespaces.NsSpreadsheetMl))
+ {
+ string activeTab = Reader.GetAttribute("activeTab");
+ int activeTabInt = int.TryParse(activeTab, out var result) ? result : 0;
+ yield return new WorkbookActRecord(activeTabInt);
+ Reader.Skip();
+ }
+ else if (!XmlReaderHelper.SkipContent(Reader))
+ {
+ break;
+ }
+ }
+ }
else if (!XmlReaderHelper.SkipContent(Reader))
{
yield break;
diff --git a/src/ExcelDataReader/ExcelDataReader.cs b/src/ExcelDataReader/ExcelDataReader.cs
index 8c0ffdc9..c489ada1 100644
--- a/src/ExcelDataReader/ExcelDataReader.cs
+++ b/src/ExcelDataReader/ExcelDataReader.cs
@@ -16,6 +16,7 @@ internal abstract class ExcelDataReader : IExcelDataReade
private IEnumerator _rowIterator;
private IEnumerator _cachedWorksheetIterator;
private List _cachedWorksheets;
+ private int _idx;
~ExcelDataReader()
{
@@ -28,6 +29,10 @@ internal abstract class ExcelDataReader : IExcelDataReade
public string VisibleState => _worksheetIterator?.Current?.VisibleState;
+ public int ActiveSheet => this.Workbook.ActiveSheet;
+
+ public bool IsActiveSheet => _idx == this.Workbook.ActiveSheet;
+
public HeaderFooter HeaderFooter => _worksheetIterator?.Current?.HeaderFooter;
// We shouldn't expose the internal array here.
@@ -213,11 +218,13 @@ public void Reset()
_worksheetIterator = null;
_rowIterator = null;
+ _idx = 0;
+
ResetSheetData();
if (Workbook != null)
{
- _worksheetIterator = ReadWorksheetsWithCache().GetEnumerator(); // Workbook.ReadWorksheets().GetEnumerator();
+ _worksheetIterator = ReadWorksheetsWithCache().GetEnumerator();
if (!_worksheetIterator.MoveNext())
{
_worksheetIterator.Dispose();
@@ -263,6 +270,9 @@ public bool NextResult()
}
_rowIterator = _worksheetIterator.Current.ReadRows().GetEnumerator();
+
+ _idx++;
+
return true;
}
diff --git a/src/ExcelDataReader/IExcelDataReader.cs b/src/ExcelDataReader/IExcelDataReader.cs
index f14a4ff1..13f48a3b 100644
--- a/src/ExcelDataReader/IExcelDataReader.cs
+++ b/src/ExcelDataReader/IExcelDataReader.cs
@@ -22,6 +22,16 @@ public interface IExcelDataReader : IDataReader
///
string VisibleState { get; }
+ ///
+ /// Gets the active sheet.
+ ///
+ int ActiveSheet { get; }
+
+ ///
+ /// Gets a value indicating whether the worksheet is active.
+ ///
+ bool IsActiveSheet { get; }
+
///
/// Gets the sheet header and footer -or- if none set.
///
diff --git a/src/TestData/Test_git_issue_642.xls b/src/TestData/Test_git_issue_642.xls
new file mode 100644
index 00000000..085d9e74
Binary files /dev/null and b/src/TestData/Test_git_issue_642.xls differ
diff --git a/src/TestData/Test_git_issue_642.xlsb b/src/TestData/Test_git_issue_642.xlsb
new file mode 100644
index 00000000..b16f6fbb
Binary files /dev/null and b/src/TestData/Test_git_issue_642.xlsb differ
diff --git a/src/TestData/Test_git_issue_642.xlsx b/src/TestData/Test_git_issue_642.xlsx
new file mode 100644
index 00000000..8a38c4f5
Binary files /dev/null and b/src/TestData/Test_git_issue_642.xlsx differ
diff --git a/src/TestData/Test_git_issue_642onesheet.xls b/src/TestData/Test_git_issue_642onesheet.xls
new file mode 100644
index 00000000..92295fc2
Binary files /dev/null and b/src/TestData/Test_git_issue_642onesheet.xls differ
diff --git a/src/TestData/Test_git_issue_642onesheet.xlsb b/src/TestData/Test_git_issue_642onesheet.xlsb
new file mode 100644
index 00000000..7793cd8e
Binary files /dev/null and b/src/TestData/Test_git_issue_642onesheet.xlsb differ
diff --git a/src/TestData/Test_git_issue_642onesheet.xlsx b/src/TestData/Test_git_issue_642onesheet.xlsx
new file mode 100644
index 00000000..a7f08112
Binary files /dev/null and b/src/TestData/Test_git_issue_642onesheet.xlsx differ