anchor.diff:  class WorksheetCollection {
     /// Returns the currently active worksheet in the workbook.
     external Worksheet getActiveWorksheet();
  +
  +  /// Adds a new worksheet to the workbook.
  +  external Worksheet add(String name);
  +}
  +
  +/// Wrapper for Excel.TableCollection class.
  +///
  +/// ``` js
  +///   Excel.TableCollection.add()
  +/// ```
  +@JS()
  +class TableCollection {
  +  /// Adds a new table to the workbook.
  +  external Table add(String address, bool hasHeader);
   }
   
   /// Wrapper for Excel.Worksheet class.
   ///
   /// ``` js
   ///   Excel.Worksheet.getRange()
  +///   Excel.Worksheet.activate()
  +///   Excel.Worksheet.getUsedRange()
   /// ```
   @JS()
   class Worksheet {
     /// Returns the range object, representing a single rectangular
     /// block of cells, specified by the address.
     external Range getRange(String address);
  +
  +  /// Activates the worksheet in the Excel UI.
  +  external void activate();
  +
  +  /// The smallest range that encompasses any cells that
  +  /// have a value or formatting assigned to them.
  +  external Range getUsedRange();
  +}
  +
  +/// Wrapper for Excel.Table class.
  +///
  +/// ``` js
  +///   Excel.Table.name
  +///   Excel.Table.getHeaderRowRange()
  +///   Excel.Table.getDataBodyRange()
  +/// ```
  +@JS()
  +class Table {
  +  /// Name of the table.
  +  external set name(String name);
  +
  +  /// Gets the range object associated with header row of the table.
  +  external Range getHeaderRowRange();
  +
  +  /// Gets the range object associated with the data body of the table.
  +  external Range getDataBodyRange();
   }
   
   /// Wrapper for Excel.Range class.
  
positive.code: /// ``` js
  ///   Excel.Range.format
  ///   Excel.Range.values
  ///   Excel.Range.load()
  /// ```
  @JS()
  class Range {
  
negative.code: @JS()
  library excel;
  
  import 'package:fixnum/fixnum.dart';
  import 'package:js/js.dart';
  
  import 'office_js.dart';
  import 'proto/insertion_order.pb.dart';
  
  /// Service class that provides dart functions to interact with Excel.
  class ExcelDart {
    static final _startAddressInt = 'A'.codeUnitAt(0);
    static final _fontName = 'Roboto';
    static final _fontSize = 12;
    static final _horizontalAlignment = 'Center';
    static final _borderStyle = 'Continuous';
  
    static final _tableHeader = [
      'Insertion Order ID',
      'Advertiser ID',
      'Campaign ID',
      'Display Name',
      'Entity Status',
      'Update Time',
      'Pacing Period',
      'Pacing Type',
      'Daily Max Micros',
      'Daily Max Impressions',
      'Budget Unit',
      'Automation Type',
      'Budget',
      'Start Date',
      'End Date'
    ];
  
    /// Waits for Office APIs to be ready and then populates the spreadsheet with
    /// entries in the [insertionOrderList]
    static void populate(List insertionOrderList) async {
      await Office.onReady(allowInterop((info) async {
        await ExcelJS.run(allowInterop((context) {
          // Grabs the current worksheet
          final sheet = context.workbook.worksheets.getActiveWorksheet();
  
          // Adds a master table
          final endAddressInt = _startAddressInt + _tableHeader.length - 1;
          final tableAddress = 'A1:${String.fromCharCode(endAddressInt)}1';
          final table = context.workbook.tables.add(tableAddress, true);
  
          // Adds and formats table header
          table.getHeaderRowRange()
            ..values = [_tableHeader]
            ..format.font.name = _fontName
            ..format.font.size = _fontSize
            ..format.font.bold = true
            ..format.horizontalAlignment = _horizontalAlignment
            ..format.borders.getItem('EdgeTop').style = _borderStyle
            ..format.borders.getItem('EdgeBottom').style = _borderStyle;
  
          // Adds and formats table body
          table.getDataBodyRange()
            ..formulas = _generateTableBody(insertionOrderList)
            ..format.font.name = _fontName
            ..format.font.size = _fontSize
            ..format.horizontalAlignment = _horizontalAlignment;
  
          // Auto-fits all used cells
          sheet.getUsedRange().getEntireColumn().format.autofitColumns();
          sheet.getUsedRange().getEntireRow().format.autofitRows();
  
          // Sets the sheet as active
          sheet.activate();
          return context.sync();
        }));
      }));
    }
  
    static List _generateTableBody(List insertionOrderList) {
      final tableBody = [];
  
      for (InsertionOrder io in insertionOrderList) {
        tableBody.add([
          io.insertionOrderId,
          io.advertiserId,
          io.campaignId,
          io.displayName,
          io.entityStatus.toString(),
          io.updateTime,
          io.pacing.pacingPeriod.toString(),
          io.pacing.pacingType.toString(),
          io.pacing.dailyMaxMicros,
          io.pacing.dailyMaxImpressions,
          io.budget.budgetUnit.toString(),
          io.budget.automationType.toString(),
          _calculateTotalBudgetAmount(io.budget.budgetSegments),
          _getStartDate(io.budget.budgetSegments.first),
          _getEndDate(io.budget.budgetSegments.last),
        ]);
      }
      return tableBody;
    }
  
    static String _calculateTotalBudgetAmount(
        List<InsertionOrder_InsertionOrderBudget_InsertionOrderBudgetSegment>
            budgetSegments) {
      var totalBudgetMicros = Int64.ZERO;
  
      for (var segment in budgetSegments) {
        totalBudgetMicros += Int64.parseInt(segment.budgetAmountMicros);
      }
  
      return (totalBudgetMicros.toDouble() / 1000000).toString();
    }
  
    static String _getStartDate(
        InsertionOrder_InsertionOrderBudget_InsertionOrderBudgetSegment
            firstSegment) {
      final startDate = firstSegment.dateRange.startDate;
      return '${startDate.month}/${startDate.day}/${startDate.year}';
    }
  
    static String _getEndDate(
        InsertionOrder_InsertionOrderBudget_InsertionOrderBudgetSegment
            lastSegment) {
      final endDate = lastSegment.dateRange.endDate;
      return '${endDate.month}/${endDate.day}/${endDate.year}';
    }
  }
  
  