# -*- coding: ISO-8859-1 -*-
import sys
sys.path.extend(['./site-packages'])
import datetime
import xlrd
from xlwt import *

import tempfile

class XlsReader:
   """
   Lesen von XLS Dateien.

   HINT:
      verwendet xlrd Moudle
      http://www.python-excel.org/
   """

   workbook    = None
   sheet       = None
   nvl         = None
   emptyval    = None
   encoding    = 'utf8'

   def __init__ (self,nvl=None,emptyval=None):
      self.nvl          = nvl
      self.emptyval     = emptyval

   def openWorkbook (self,filename,sheetid=0,encoding_override='utf8'):
      """
      Oeffnen eines Arbeitsblattes

      @param   filename          Dateiname und Pfad auf ein existierendes Excel
      @param   sheetid           Kennzeichen des Arbeitsblattes
         Vorgabewert 0 (1. Arbeitsblatt)
         Als Integer   
            es wird das Arbeitsblatt mit der
            uebergebenen Nummer genommen
         Als Zeichenkette 
            das Arbeitsblatt mit dem Uebergenen
            Namen wird ausgewaehlt.

     HINT:
        Kann kein Arbeitsblatt gefunden werden
        wird eine Ausnahme geworten
      """
      try:
         self.workbook = xlrd.open_workbook(filename,encoding_override)
      except IOError as e:
          raise Exception("I/O error({0}): {1}".format(e.errno, e.strerror))
      
      self.encoding = encoding_override

      if isinstance(sheetid,str):         
         self.sheet = self.workbook.sheet_by_name(sheetid)
      elif isinstance(sheetid,int):
         self.sheet = self.workbook.sheet_by_index(sheetid)
      else:
         raise ValueError("Der Parameter sheetid muss Integer oder String sein.")

   def getWorkbook(self):
      """
      Liefert workbook objekt

      @return  workbook
      """
      return self.workbook

   def getRows(self):
      """
      Liefert die Anzahl der Zeilen in aktuellem Sheet

      @return  cnt
      """
      return self.sheet.nrows

   
   def getValue (self,row=0,col=0):
      """
      Liefert den Inhalt einer Zelle oder ein Kennzeichen wenn nicht gefunden.

      @param   row         Zeile (Null-Relativ)
      @param   col         Spalte (Null-Relativ)

      @return  Inhalt

      """
      retval = None
      try:
         celltype = self.sheet.cell_type(row,col)
         if celltype == xlrd.XL_CELL_EMPTY:
            retval = self.emptyval
         
         elif celltype == xlrd.XL_CELL_BLANK:
            retval = self.sheet.cell_value(row,col)

         elif celltype == xlrd.XL_CELL_NUMBER:
            retval = self.sheet.cell_value(row,col)

         elif celltype == xlrd.XL_CELL_DATE:
            ms_date_number = self.sheet.cell_value(row,col)
            year, month, day, hour, minute, second = xlrd.xldate_as_tuple(ms_date_number, self.workbook.datemode)
            py_date = datetime.datetime(year, month, day, hour, minute)
            retval = py_date
         
         elif celltype == xlrd.XL_CELL_TEXT:
            retval = self.sheet.cell_value(row,col).encode(self.encoding)
         
         elif celltype == xlrd.XL_CELL_ERROR:            
            retval = xlrd.error_text_from_code.get(self.sheet.cell_value(row,col))

         elif celltype == xlrd.XL_CELL_BOOLEAN:
            retval = True if self.sheet.cell_value(row,col) else False

      except:
         retval = self.nvl

      return retval


   def datarow(self,row):
      """
      Liefert eine Liste von allen Zellen der Datenzeile (row)
      Dabei werden die Inhalte durch getValue erzeugt.

      @row        Datenzeile (Null-Relativ)

      @return     Liste (None wenn keine Vorhanden)

      """
      retval = []
      therow = self.sheet.row(row)

      for col in range(0,self.sheet.ncols):
         retval.append(self.getValue(row,col))
      return retval
   
   def allRows(self,firstline=None, lastline=None):
      """
      Itteriert ueber alle Zeilen eines Arbeitsblattes (solange nicht
      anders angegegen und liefert fuer jede Zeile eine Liste mit Werten,
      welche durch getValue erzeugt wurde.

      @param   firstline         Beginn mit Datenzeile oder mit 0
      @param   lastline          Ende mit Datenzeile oder alle

      """

      firstline = 0                if firstline is None else firstline
      lastline  = self.sheet.nrows if lastline is None else lastline
      
      for row in range(firstline,lastline):
         yield xls.datarow(row)      
   
   def closeWorkbook(self):
      """
      Schlieszen Arbeitsblatt und Arbeitsbuch
      """
      del self.sheet
      del self.workbook

   

class XlsWriter:
   """
   Lesen von XLS Dateien.

   HINT:
      verwendet xlrd Moudle
      http://www.python-excel.org/
   """
   workbook    = None
   sheet       = None
   xlsfile     = None

   sheets      = []


   def addSheet(self,sheetname):
      """
      Fuegt der Arbeitsmappe ein Arbeitsblatt hinzu

      @param      sheetname         Name des Arbeitsblattes

      HINT:
         das aktelle Arbeitsblatt wird gesetzt

      """
      assert self.workbook is not None,"Noch keine Arbeitsmappe angelegt"
      self.sheet = self.workbook.add_sheet(sheetname)
      self.sheets.append(sheetname)
         

   def openWorkbook(self,sheetname=None,encoding=None):
      """
      Anlegen einer Arbeitsmappe

      @param   shettname         Anlegen eines Arbeitsblattes                                 wenn Name uebergeben.
      @param   encoding          Encoding, Vorgabewert 'windows-1252'

      HINT:
         das aktelle Arbeitsblatt wird gesetzt
      
      """

      encoding = 'windows-1252' if encoding is None else encoding
      self.workbook = Workbook(encoding=encoding)
      if sheetname is not None:
         self.addSheet(sheetname)

   def currentSheet(self,sheetid):
      """
      Setzen des aktellen Arbeitsblattes auf den uebergebenen Namen

      @param   sheetid     Kann String oder Integer sein
      """
      if isinstance(sheetid,str):         
         sheetid = self.sheets.index(sheetid)
         self.sheet = self.workbook.get_sheet(sheetid)
      elif isinstance(sheetid,int):
         self.sheet = self.workbook.get_sheet(sheetid)
      else:
         raise ValueError("Der Parameter sheetid muss Integer oder String sein.")

   
   def setCell(self,row,col,value,sheetid=None):
      """
      Schreibt den Inhalt von Value auf das aktuelle Arbeitsblatt.
      Dabei wird die Position row, col verwendet.

      @param row        Zeile
      @param col        Spalte
      @param value      Inhalt
      @param sheetname  Optional,
                        es wird auf das uebergebene Arbeitsblatt geschrieben
                        dabei wird der Wert des aktellen Arbeitsblattes nicht 
                        veraendert.
      """

      curSheet = None

      if sheetid is None:
         curSheet = self.sheet
      elif isinstance(sheetid,str):         
         sheetid = self.sheets.index(sheetid)
         curSheet = self.workbook.get_sheet(sheetid)
      elif isinstance(sheetid,int):
         curSheet = self.workbook.get_sheet(sheetid)         
      else:
         raise ValueError("Der Parameter sheetid muss Integer oder String sein.")      
         
      curSheet.write(row,col,value)
   

   def write(self,xlsfile=None):
      """
      Schreiben des XLS Files

      @param   xlsfile  Output Datei
         
      HINT:
         Gueltige Parametertypen
            + None         Es wird ein temporaeres File angelegt
            + String       es wird eine Datei mit uebergebenen Namen
                           eingerichtet
            + fileobjekt   Es wird das uebergebene Filehandle verwendet
                           
      """

      if isinstance(xlsfile,str):
         self.xlsfile = open(xlsfile,'wb')
      elif isinstance(xlsfile,file):
         self.xlsfile = xlsfile
      elif xlsfile is None:
         self.xlsfile = tempfile.TemporaryFile(delete=False)
      else:
         raise Exception('Parameter muss den Type None, String oder Filehandle haben.')
         
      try:
         self.workbook.save(self.xlsfile)
      except Exception,e:
         raise Exception(e)

      
if __name__ == '__main__':
   
   xls = XlsReader()
   xls.openWorkbook('myfile.xlsx','Data')

   for row in range(xls.sheet.nrows):
      print row


   for row in xls.allRows():
      print row[0],row[1]
   xls.closeWorkbook()

   xls = XlsWriter()
   xls.openWorkbook()
   xls.addSheet('Tabelle1')
   xls.addSheet('Tabelle2')
   
   xls.setCell(1,1,'EinTest tabelle 2')
   xls.setCell(1,1,'EinTest tabelle 1','Tabelle1')
   xls.setCell(2,1,'EinTest tabelle 2,zeile2')
   xls.currentSheet('Tabelle1')
   for row  in range(128):   
      xls.setCell(row,0,"Row: {0}".format(row))
   
   f = open ('test.xls','wb')
   xls.write(f)
   print xls.xlsfile.name
