Dynamic Excel Sheet Extraction in SSIS – Load Data from All Excel Tabs and Capture Sheet Names

Introduction

When working with Excel files, it’s common to receive workbooks containing multiple worksheets (tabs). In many ETL scenarios, you may need to:

  • Import data from all worksheets dynamically.
  • Avoid hardcoding sheet names.
  • Track which worksheet each row originated from.

In this article, we’ll demonstrate how to dynamically read data from all Excel sheets using ZappySys Excel Source and capture the corresponding Sheet Name as an additional column in the output.

Problem Statement

Consider an Excel workbook containing multiple sheets:

1. MySheet1
2. MySheet2
3. MySheet3
...

You need to:

  • Read data from every worksheet.
  • Avoid manually updating the package whenever a new sheet is added.
  • Add the sheet name to every imported record.

Desired Output

SheetName Column1 Column2 Column3
MySheet1 Value1 Value2 Value3
MySheet2 Value1 Value2 Value3
MySheet3 Value1 Value2 Value3

Solution Overview

The approach consists of two phases:

Phase 1 – Retrieve Sheet Names

Use Excel Source to query the special metadata table:

SELECT *
FROM [__SheetList__]

This returns:

  • SheetName
  • SheetOrder

Store the results in an SSIS Object Variable using a Recordset Destination.

Phase 2 – Loop Through Each Sheet

Use a ForEach Loop Container to iterate through the sheet list and:

  1. Read data from the current worksheet.
  2. Add the current SheetName as a new column.
  3. Load data into the destination.

SSIS Package Design

Control Flow

The package contains:

  1. Data Flow Task – Get Sheet List
  2. ForEach Loop Container

Step 1 – Get All Sheet Names

Add a Data Flow Task.

Configure Excel Source

Set the source query as:

SELECT *
FROM [__SheetList__]

Preview output:

SheetName SheetOrder
MySheet1 1
MySheet2 2
MySheet3 3


Step 2 – Store Sheet List in an Object Variable

Add a Recordset Destination.

Create an SSIS Object Variable:

User::objSheetList

Configure Recordset Destination to store the sheet list into this variable.

Recordset Destination Settings

  • Variable Name: User::objSheetList

Map:

  • SheetName
  • SheetOrder


Step 3 – Configure ForEach Loop Container

Add a ForEach Loop Container.

Collection Tab

Configure:

  • Enumerator: ForEach ADO Enumerator
  • Source Variable: User::objSheetList

Variable Mappings

Create variables:

User::SheetName
User::SheetOrder

Map:

Variable Index
SheetName 0
SheetOrder 1


Step 4 – Read Data from Current Sheet

Inside the ForEach Loop, add a new Data Flow Task.

Configure Excel Source

Switch to Query Mode and use:

SELECT *
FROM [?]

Click Insert Variable and select:

User::SheetName

This allows Excel Source to dynamically query the current worksheet during each loop iteration.


Step 5 – Add Sheet Name to Output

Add a Derived Column Transformation.

Create a new column:

SheetName

Expression:

@[User::SheetName]

This appends the worksheet name to every row returned from the current sheet.


Step 6 – Load Data into Destination

Connect the Derived Column transformation to your desired destination:

  • SQL Server
  • CSV File
  • Azure SQL
  • Snowflake
  • Any supported destination


Example Output

Excel Workbook

1. MySheet1
2. MySheet2
3. MySheet3

Result

SheetName Name Country
MySheet1 John Smith IN
MySheet1 Jane Doe US
MySheet2 Michael Brown UK
MySheet3 Sarah Wilson AU

Benefits of This Approach

:white_check_mark: No hardcoded sheet names

:white_check_mark: Automatically handles newly added worksheets

:white_check_mark: Easy to maintain

:white_check_mark: Captures source worksheet information

:white_check_mark: Works with any number of sheets

:white_check_mark: Ideal for dynamic ETL processes


Conclusion

Using the special __SheetList__ metadata table along with a ForEach Loop Container, you can dynamically process every worksheet in an Excel workbook and capture the corresponding sheet name for each record.

This approach is particularly useful when workbook structures change frequently or when business users add new worksheets regularly.

If you’re using ZappySys Excel Source, this method provides a flexible and scalable way to load data from all tabs without modifying your SSIS package whenever sheet names change.