Search Results for

    Show / Hide Table of Contents

    How To: Export Data To Microsoft Excel

    For reporting purposes it is often necessary to automatically export data into Microsoft Office Excel. You could for instance create a timesheet export script that automatically creates an excel pivot table report per user and sends this report via email.

    time cockpit supports two ways of exporting data to Microsoft Office Excel:

    • Use time cockpit's built-in export function.
    • In case you need something very special (e.g. special formatting of the resulting Microsoft Office Excel file) you can use Microsoft Office automation in IronPython.

    Using Built-In Microsoft Office Excel Export Function

    The following sample shows how to export the result of a TCQL query using an export template file inside a script:

    Note

    The Export method shown in the code below expects either a template file or a list definition. If you specify a template the list definition is ignored. If you do not specify a template file you have to specify a list definition (i.e. template is automatically built based on the list definition).

    clr.AddReference("TimeCockpit.Data.Export")
    from TimeCockpit.Data.Export.Excel import *
    from System.Threading import CancellationToken
    
    resultingRows = Context.Select("From T In Timesheet Where T.APP_BeginTime > #2010-01-01# Select T")
    sourceList = Context.Model.ModelEntityViews["APP_TimesheetList"].Configuration.Columns
    
    XlsxExporter2.ExportToFile(
      "c:\\temp\\Template.xlsx",    # Path to template file  
      "c:\\temp\\export.xlsx",      # Target file name
      resultingRows,                # Rows that should be exported (has to be a list of entity objects)
      sourceList,                   # List definition that acts as the source for the export
      None,                         # Reserved; always pass None here
      CancellationToken(False))     # Cancellation token that could be used to cancel the export
    

    Using Microsoft Office Automation in a Script

    The following sample shows how to generate an Microsoft Office Excel file using Microsoft Office automation. The script loads a template workbook, creates one sheet per user by copying a worksheet and fills the sheet with time sheet rows. Holidays and weekends are specially formatted.

    import clr
    clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
    clr.AddReference("System.Core")
    from Microsoft.Office.Interop import *
    from Microsoft.Office.Interop.Excel import *
    from System import *
    from System.Linq import Enumerable
    
    # Helper function that sets the background of the entire row 
    def ColorizeRow(cell):
      cell.EntireRow.Interior.ThemeColor = XlThemeColor.xlThemeColorDark1
      cell.EntireRow.Interior.TintAndShade = -0.249977111117893 
    
    # Helper function that checks if a certain day if no working day 
    def IsDayOff(day, holidays):
      return day.DayOfWeek == DayOfWeek.Saturday or day.DayOfWeek == DayOfWeek.Sunday \
        or Enumerable.Count(holidays, lambda h: h.LegalHolidayDate.Day == day.Day) > 0 
    
    # Helper function that colorizes the entire day if the day is off 
    def HandleRowColor(currentDayDate, cell, holidays):
      if IsDayOff(currentDayDate, holidays):
        ColorizeRow(cell)
    
    # Creates an Excel worksheet for a specific user and month 
    def AddWorksheet(user, year, month, workbook):
      # Get all timesheets for the user
      timesheets = Context.SelectWithParams({
        "Query": "From T In Timesheet Where T.UserDetail.Username = @Username And :Year(T.BeginTime) = @YearFilter And :Month(T.BeginTime) = @MonthFilter Order By T.BeginTime Select T",
        "@Username": user.Username,
        "@YearFilter": Decimal(year),
        "@MonthFilter": Decimal(month) })
    
      # Get holidays for the corresponding month
      holidays = Context.SelectWithParams({
        "Query": "From H In LegalHoliday Where :Year(H.LegalHolidayDate) = @YearFilter And :Month(H.LegalHolidayDate) = @MonthFilter Order By H.LegalHolidayDate Select H",
        "@YearFilter": Decimal(year),
        "@MonthFilter": Decimal(month) })
    
      # Add sheet for user
      workbook.Worksheets["Tabelle1"].Copy(Before = workbook.Worksheets[1])
      ws = workbook.Worksheets[1]
      ws.Name = user.Lastname + ", " + user.Firstname
      ws.Activate()
    
      rowIndex = 2
      totalWorkingHours = 0
      hoursPerDay = user.WeeklyHoursOfWork / 5
      prevDay = 0 
    
      # Loop over all days of the month 
      for currentDay in range(1, DateTime(year, month, 1).AddMonths(1).AddDays(-1).Day + 1):
        currentDayDate = DateTime(year, month, currentDay)
        dailyTimesheets = Enumerable.Where(timesheets, lambda t: t.BeginTime.Day == currentDay)
    
        if Enumerable.Count(dailyTimesheets) > 0:
          # There are timesheets for this day 
          for timesheet in dailyTimesheets:
            # Add row for timesheet
            HandleRowColor(currentDayDate, ws.Cells[rowIndex, 1], holidays)
            if prevDay != timesheet.BeginTime.Day:
              # Don't repeat day index for mulitple rows of the same day
              ws.Cells[rowIndex, 1].Value2 = timesheet.BeginTime.Day
            ws.Cells[rowIndex, 2].Value2 = timesheet.BeginTime
            ws.Cells[rowIndex, 3].Value2 = timesheet.EndTime
            ws.Cells[rowIndex, 4].Value2 = timesheet.DurationInHours / 24
            ws.Cells[rowIndex, 5].Value2 = timesheet.Description
            totalWorkingHours = totalWorkingHours + timesheet.DurationInHours
            prevDay = timesheet.BeginTime.Day
            rowIndex = rowIndex + 1 
        else:
          # There are no timesheets for this day
          HandleRowColor(currentDayDate, ws.Cells[rowIndex, 1], holidays)
          ws.Cells[rowIndex, 1].Value2 = currentDay 
          rowIndex = rowIndex + 1 
    
      # Add sums
      ws.Cells[rowIndex,2].Value2 = 'Gesamt:'
      ws.Cells[rowIndex,4].Value2 = (totalWorkingHours)/ 24
      rowIndex = rowIndex + 1 
    
    # Open Excel (visible just for demo purposes)
    ex = Excel.ApplicationClass()   
    ex.Visible = True
    ex.DisplayAlerts = False   
    workbook = ex.Workbooks.Open(r"c:\temp\MonthlyReport.xlsx")
    
    users = Context.Select("From U In UserDetail Order By U.Username Select U")
    for user in users:
      AddWorksheet( user, 2017, 5, workbook )
    
    print "Done!"
    

    Using an Action to Integrate Microsoft Office Excel Export in the User Interface

    You can convert an export script into an Action to offer a button in time cockpit's user interface that exports the data of the selected row in a list. The following example shows how the sample shown above can be added as an action to the entity APP_UserDetail:

    Note

    Note that the action's code must only contain one top level def statement! If you need helper functions you have to define them as nested functions inside the one and only top level function (see sample code below).

    import clr
    clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
    clr.AddReference("System.Core")
    from Microsoft.Office.Interop import *
    from Microsoft.Office.Interop.Excel import *
    from System import *
    from System.Linq import Enumerable
    
    def ExportTimesheetProtocolToExcel(actionContext):
      # Helper function that sets the background of the entire row 
      def ColorizeRow(cell):
        cell.EntireRow.Interior.ThemeColor = XlThemeColor.xlThemeColorDark1
        cell.EntireRow.Interior.TintAndShade = -0.249977111117893 
    
      # Helper function that checks if a certain day if no working day 
      def IsDayOff(day, holidays):
        return day.DayOfWeek == DayOfWeek.Saturday or day.DayOfWeek == DayOfWeek.Sunday \
          or Enumerable.Count(holidays, lambda h: h.LegalHolidayDate.Day == day.Day) > 0 
    
      # Helper function that colorizes the entire day if the day is off 
      def HandleRowColor(currentDayDate, cell, holidays):
        if IsDayOff(currentDayDate, holidays):
          ColorizeRow(cell)
    
      # Creates an Excel worksheet for a specific user and month 
      def AddWorksheet(user, year, month, workbook):
        # Get all timesheets for the user
        timesheets = Context.SelectWithParams({
          "Query": "From T In Timesheet Where T.UserDetail.Username = @Username And :Year(T.BeginTime) = @YearFilter And :Month(T.BeginTime) = @MonthFilter Order By T.BeginTime Select T",
          "@Username": user.Username,
          "@YearFilter": Decimal(year),
          "@MonthFilter": Decimal(month) })
    
        # Get holidays for the corresponding month
        holidays = Context.SelectWithParams({
          "Query": "From H In LegalHoliday Where :Year(H.LegalHolidayDate) = @YearFilter And :Month(H.LegalHolidayDate) = @MonthFilter Order By H.LegalHolidayDate Select H",
          "@YearFilter": Decimal(year),
          "@MonthFilter": Decimal(month) })
    
        # Add sheet for user
        workbook.Worksheets["Tabelle1"].Copy(Before = workbook.Worksheets[1])
        ws = workbook.Worksheets[1]
        ws.Name = user.Lastname + ", " + user.Firstname
        ws.Activate()
    
        rowIndex = 2
        totalWorkingHours = 0
        hoursPerDay = user.WeeklyHoursOfWork / 5
        prevDay = 0 
    
        # Loop over all days of the month 
        for currentDay in range(1, DateTime(year, month, 1).AddMonths(1).AddDays(-1).Day + 1):
          currentDayDate = DateTime(year, month, currentDay)
          dailyTimesheets = Enumerable.Where(timesheets, lambda t: t.BeginTime.Day == currentDay)
    
          if Enumerable.Count(dailyTimesheets) > 0:
            # There are timesheets for this day 
            for timesheet in dailyTimesheets:
              # Add row for timesheet
              HandleRowColor(currentDayDate, ws.Cells[rowIndex, 1], holidays)
              if prevDay != timesheet.BeginTime.Day:
                # Don't repeat day index for mulitple rows of the same day
                ws.Cells[rowIndex, 1].Value2 = timesheet.BeginTime.Day
              ws.Cells[rowIndex, 2].Value2 = timesheet.BeginTime
              ws.Cells[rowIndex, 3].Value2 = timesheet.EndTime
              ws.Cells[rowIndex, 4].Value2 = timesheet.DurationInHours / 24
              ws.Cells[rowIndex, 5].Value2 = timesheet.Description
              totalWorkingHours = totalWorkingHours + timesheet.DurationInHours
              prevDay = timesheet.BeginTime.Day
              rowIndex = rowIndex + 1 
          else:
            # There are no timesheets for this day
            HandleRowColor(currentDayDate, ws.Cells[rowIndex, 1], holidays)
            ws.Cells[rowIndex, 1].Value2 = currentDay 
            rowIndex = rowIndex + 1 
    
        # Add sums
        ws.Cells[rowIndex,2].Value2 = 'Gesamt:'
        ws.Cells[rowIndex,4].Value2 = (totalWorkingHours)/ 24
        rowIndex = rowIndex + 1 
    
      # make sure that input set contains at least one object 
      if (Enumerable.Count[EntityObject](actionContext.InputSet) > 0):
        # Open Excel (visible just for demo purposes)
        ex = Excel.ApplicationClass()   
        ex.Visible = True
        ex.DisplayAlerts = False   
        workbook = ex.Workbooks.Open(r"C:\temp\MonthlyReport.xlsx")
    
        for user in actionContext.InputSet:
          AddWorksheet( user, 2017, 5, workbook )
    
    • Improve this Doc
    In This Article
    Back to top Copyright © 2020 software architects gmbh