Export Multiple Tables to Single Excel spreadsheet

Not sure where the idea came from, but exportExcel() is not documented to accept sheet names.

Here is a modified version of a function I wrote in this thread:

def listToExcel(datasetList, fileName = '', sheetNames = 'Sheet {}', dateFormat = 'yyyy-mm-dd hh:mm:ss'):
	''' Convert a list of datasets to Excel
			params:
	    	datasetList:	The list of datasets to convert. Valid types are:
	        				- com.inductiveautomation.ignition.common.BasicDataset
							- com.inductiveautomation.ignition.common.script.builtin.DatasetUtilities$PyDataSet
							- com.inductiveautomation.ignition.common.JsonDataset
			fileName:	The name to save the Excel file. If omitted, the output will be a byte array.
						This is useful to use with perspective (e.g. system.perspective.download)
			sheetNames:	List of names The tab name of the workbook. Default is Sheet 1, Sheet 2, etc.
			dateFormat:	How dates should be formatted, e.g. 'yyyy-mm-dd hh:mm:ss'. 
			            Note that Excel does not use capital letters, because... Microsoft.
			            The script will auto lower-case your format.       
	'''
	import org.apache.poi.ss.usermodel.Cell as Cell
	import org.apache.poi.ss.usermodel.Row as Row
	import org.apache.poi.ss.usermodel.Sheet as Sheet
	import org.apache.poi.ss.usermodel.Workbook as Workbook
	import org.apache.poi.xssf.usermodel.XSSFWorkbook as XSSFWorkbook
	import org.apache.poi.xssf.usermodel.XSSFDataFormat as XSSFDataFormat
	from java.io import FileOutputStream, ByteArrayOutputStream
	
	if fileName == '':
		output = ByteArrayOutputStream()
	else:
		output = FileOutputStream(fileName)
	# Create workbook
	wb = XSSFWorkbook()
	
	for sheetIndex, dsIn in enumerate(datasetList):
		dsType = str(type(dsIn))
		
		# Convert to PyDataSet, if needed
		if 'com.inductiveautomation.ignition.common.BasicDataset' in dsType:
			pyDS = system.dataset.toPyDataSet(dsIn)
		elif 'com.inductiveautomation.ignition.common.JsonDataset' in dsType:
			pyDS = system.dataset.toPyDataSet(dsIn)
		elif 'com.inductiveautomation.ignition.common.script.builtin.DatasetUtilities$PyDataSet' in dsType:
			pyDS = dsIn
		else:
			raise Exception('Not a valid DataSet')
	
		# Create Sheet
		if sheetNames == 'Sheet {}':
			sheet = wb.createSheet(sheetNames.format(sheetIndex + 1))
		else:
			sheet = wb.createSheet(sheetNames[sheetIndex])
	
		# Create formatter
		fmt = wb.createDataFormat()
	
		# Create style for headers
		headerStyle = wb.createCellStyle()
		headerFont = wb.createFont()
		headerFont.setBold(True)
		headerFont.setFontHeightInPoints(10)
		headerFont.setFontName('Arial')
		headerStyle.setFont(headerFont)
	
		# Create style for data
		rowStyle = wb.createCellStyle()
		rowFont = wb.createFont()
		rowFont.setBold(False)
		rowFont.setFontHeightInPoints(10)
		rowFont.setFontName('Arial')
		rowStyle.setFont(rowFont)
	
		# Create style for dates.
		dateStyle = wb.createCellStyle()
		dateFont = wb.createFont()
		dateFont.setBold(False)
		dateFont.setFontHeightInPoints(10)
		dateFont.setFontName('Arial')
		dateStyle.setFont(dateFont)
		dateStyle.setDataFormat(fmt.getFormat(dateFormat.lower()))
	
		# Create header row in the sheet
		headerRow = sheet.createRow(0)
		for i, col in enumerate(pyDS.getColumnNames()):
			cell = headerRow.createCell(i)
			cell.setCellStyle(headerStyle)
			cell.setCellValue(col)
		# Create data rows	
		for i, row in enumerate(pyDS):
			dataRow = sheet.createRow(i+1)
			for j, col in enumerate(list(row)):
				cell = dataRow.createCell(j)
				cell.setCellValue(col)
				cell.setCellStyle(rowStyle)
				# Check if it's a date, and set cell format accordingly 
				if 'java.util.Date' in str(type(col)):
					cell.setCellStyle(dateStyle)
		
		# Resize the columns		
		for i in range(pyDS.getColumnCount()):
			sheet.autoSizeColumn(i)	
	
	wb.write(output)
	output.close()
	if fileName == '':
		return output.toByteArray()
	else:
		return

Sample usage:

sampleHeaders1 = ['col1', 'col2', 'col3']
sampleData1 = [[system.date.parse('2023-06-01 00:00:00'), 'Row1', 1],
               [system.date.parse('2023-06-02 00:00:00'), 'Row2', 2],
               [system.date.parse('2023-06-03 00:00:00'), 'Row3', 3]
              ]

sampleHeaders2 = ['col10', 'col20', 'col30']
sampleData2 = [[system.date.parse('2023-06-11 00:00:00'), 'Row11', 11],
               [system.date.parse('2023-06-12 00:00:00'), 'Row12', 12],
               [system.date.parse('2023-06-13 00:00:00'), 'Row13', 13]
              ]

dataset1 = system.dataset.toDataSet(sampleHeaders1, sampleData1)
dataset2 = system.dataset.toDataSet(sampleHeaders2, sampleData2)

util.dataset.listToExcel([dataset1, dataset2], fileName='C:/Test/multisheetTest.xlsx', sheetNames=['MySheet1', 'TheSecondSheet'])

image

image