datapumps
Version:
Node.js ETL (Extract, Transform, Load) toolkit for easy data import, export or transfer between systems.
106 lines (94 loc) • 3.38 kB
text/coffeescript
# OOXML Excel (.xlsx) writer mixin for node-datapumps.
#
# Usage:
# * Require excel writer mixin:
# ```coffee
# { ExcelWriterMixin } = require('datapumps/mixins')
# ```
#
# * The parameter of the mixin is a function than will be executed when the mixin is added to a pump. Use that function to create your workbook and headers:
#
# ```coffee
# pump
# .mixin ExcelWriterMixin ->
# pump.createWorkbook 'test.xlsx'
# pump.createWorksheet 'MySheet'
# pump.writeHeaders [ 'Name', 'Code' ]
# ```
#
# * Use `.writeRow` in the `.process` method of the pump to write a row in excel:
#
# ```coffee
# pump
# .process (product) ->
# pump.writeRow [ product.name, product.code ]
# ```
#
# Complete example:
# ```coffee
# customersExcelSheet = new Pump
# customersExcelSheet
# .from <yoursource>
# .mixin ExcelWriterMixin ->
# @createWorkbook 'test.xlsx'
# @createWorksheet 'Customers'
# @writeHeaders [
# 'First name'
# 'Last name'
# 'Zip'
# 'City'
# ]
# .process (customer) ->
# @writeRow [
# customer.first_name
# customer.last_name
# customer.zip
# customer.city
# ]
# ```
#
# Based on excel4node (https://github.com/natergj/excel4node).
#
excel4node = require('excel4node')
ExcelWriterMixin = (onMixin) ->
(target) ->
# This mixin extends the `target` object. It add an `_excel` property and the methods below:
target._excel = {}
# Creates the workbook if not already created.
target.createWorkbook = (path) ->
throw new Error 'Workbook already created' if @_excel.workbook?
@_excel.workbook = new excel4node.WorkBook()
@_excel.path = path
@_excel.boldStyle = @_excel.workbook.Style()
@_excel.boldStyle.Font.Bold()
@_excel.workbook
# Create a new worksheet with given name. Any subsequent cell accessor methods (e.g.
# `.writerHeader`, `.writeRow`) will write to the new worksheet.
target.createWorksheet = (name) ->
throw new Error 'Use createWorkbook before creating worksheet' if !@_excel.workbook?
@_excel.worksheet = @_excel.workbook.WorkSheet(name)
@_excel.currentRow = 1
# Returns current worksheet.
target.currentWorksheet = ->
@_excel.worksheet
# Writes header row. See usage example at the top.
target.writeHeaders = (headers) ->
throw new Error 'Use createWorksheet before writing headers' if !@_excel.worksheet?
throw new Error 'Use writeHeaders before writing any rows to the worksheet' if @_excel.currentRow != 1
@_writeHeader index, header for header, index in headers
@_excel.currentRow = 2
@
target._writeHeader = (index, header) ->
@_excel.worksheet.Cell(1, index + 1)
.String(header)
.Style(@_excel.boldStyle)
# Writes a new row in the worksheet. See usage example at the top.
target.writeRow = (columns) ->
throw new Error 'Use createWorksheet before writing rows' if !@_excel.worksheet?
@_excel.worksheet.Cell(@_excel.currentRow, index + 1).String(value) for value, index in columns
@_excel.currentRow++
# Write the xlsx file when pumping is ended.
target.on 'end', ->
target._excel.workbook.write target._excel.path if target._excel.workbook?
onMixin.apply(target, [])
module.exports = ExcelWriterMixin