public static int Run(ExcelToWintouchOptions options)
        {
            df = new DataFormatter();
            ExcelToWintouch.options = options;

            IWorkbook workbook;

            using (FileStream file = new FileStream(options.FicheiroExcel, FileMode.Open, FileAccess.Read))
            {
                using (StreamWriter outputStream = new StreamWriter(options.FicheiroWintouch))
                {
                    outputStream.WriteLine("WCONTAB5.60");

                    workbook = new XSSFWorkbook(file);
                    ISheet sheet = workbook.GetSheet(options.FolhaExcel);

                    int colStartValores = 5;
                    int colEndValores   = 13;
                    int numValores      = colEndValores - colStartValores;

                    Classificacoes classificacoes = ReadClassificacoes(sheet, numValores);

                    int colData    = 0;
                    int colTipoDoc = 1;
                    int colNumDoc  = 2;
                    int colNIF     = 3;
                    int colNome    = 4;

                    for (int rowIdx = 1; rowIdx <= sheet.LastRowNum; rowIdx++)
                    {
                        IRow row = sheet.GetRow(rowIdx);
                        if (row != null) //Se a linha tiver dados continua
                        {
                            string nifValStr = df.FormatCellValue(row.GetCell(colNIF));
                            if (nifValStr != null && nifValStr.Length > 0)
                            {
                                decimal[] valores = new decimal[colEndValores - colStartValores + 1];

                                for (int col = colStartValores; col <= colEndValores; col++)
                                {
                                    valores[col - colStartValores] = (decimal)row.GetCell(col).NumericCellValue;
                                }

                                Fatura fatura = new Fatura(row.GetCell(colData).DateCellValue,
                                                           df.FormatCellValue(row.GetCell(colTipoDoc)),
                                                           df.FormatCellValue(row.GetCell(colNumDoc)),
                                                           df.FormatCellValue(row.GetCell(colNIF)),
                                                           df.FormatCellValue(row.GetCell(colNome)),
                                                           valores);

                                ExportFatura(outputStream, fatura, classificacoes);
                            }
                        }
                    }
                }
            }
            return(0);
        }
        private static string GetFaturaDescricao(Fatura fatura)
        {
            string descricao = Smart.Format(options.FormatoDescricao, new { fatura });

            if (descricao.Length > 50)
            {
                descricao = descricao.Substring(0, 50);
            }
            return(descricao);
        }
        private static void ExportFatura(StreamWriter fileStream, Fatura fatura, Classificacoes classificacoes)
        {
            int numLinha = 0;

            for (int i = 0; i < fatura.valores.Length; i++)
            {
                //Escreve uma linha por cada valor da fatura (se o valor não for 0)
                decimal valor = fatura.valores[i];
                if (valor != 0)
                {
                    if (!classificacoes.contasPorValor[i].contas.ContainsKey(fatura.TipoDoc))
                    {
                        throw new Exception(String.Format("Tipo de documento \"{0}\" desconhecido (NumDoc {1})", fatura.TipoDoc, fatura.NumDoc));
                    }

                    ContasParaValor contasParaValor = classificacoes.contasPorValor[i];

                    ExportLinhaFatura(fileStream, fatura, valor, contasParaValor, classificacoes, numLinha);
                    numLinha++;
                }
            }
        }