package com.ejie.aa21b.view;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.view.document.AbstractExcelView;

import com.ejie.aa21b.model.Aa21b12s01;
import com.ejie.aa21b.model.Aa21b13s01;
import com.ejie.aa21b.model.Aa21b14s01;
import com.ejie.aa21b.model.Aa21b15s01;
import com.ejie.aa21b.model.Aa21b20s01;
import com.ejie.aa21b.model.Aa21b21s01;
import com.ejie.aa21b.model.Aa21b25s01;
import com.ejie.aa21b.model.Aa21b29s01;
import com.ejie.aa21b.model.NoraMunicipio;
import com.ejie.aa21b.model.NoraProvincia;
import com.ejie.aa21b.util.Aa21bConstantes;

/**
 * Crea el excel de listado de expedientes (Consultas y listados)
 * 
 *  
 * 
 */
public class ExcelAa21bFichaExpedienteView extends AbstractExcelView {
	private static final Logger logger = LoggerFactory
			.getLogger(ExcelAa21bFichaExpedienteView.class);
	/** Message source for i18n lookups */
	@Autowired
	private MessageSource messageSource;

	/**
	 * 
	 * @return MessageSource
	 */
	public MessageSource getMessageSource() {
		return messageSource;
	}

	/**
	 * 
	 * @param messageSource
	 *            MessageSource
	 */
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}

	/**
	 * 
	 */
	public ExcelAa21bFichaExpedienteView() {

	}

	/**
	 * 
	 * @param msgSource
	 *            MessageSource
	 */
	public ExcelAa21bFichaExpedienteView(MessageSource msgSource) {
		this.messageSource = msgSource;

	}

	/**
	 * Calcula las celdas tipo fórmula para que se muestren los resultados
	 * correctamente
	 * 
	 * @param wb
	 *            HSSFWorkbook
	 */
	public void evaluateAllFormulaCells(HSSFWorkbook wb) {
		HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
		Iterator rit;
		Iterator cit;
		for (int i = 0; i < wb.getNumberOfSheets(); ++i) {
			HSSFSheet sheet = wb.getSheetAt(i);

			for (rit = sheet.rowIterator(); rit.hasNext();) {
				Row r = (Row) rit.next();

				for (cit = r.cellIterator(); cit.hasNext();) {
					Cell c = (Cell) cit.next();
					if (c.getCellType() == 2)
						try {
							evaluator.evaluateFormulaCell(c);
						} catch (Exception e) {
						}
				}
			}
		}
	}

	Map<String, HSSFCellStyle> estilos;

	/**
	 * Obtener el nombre de fichero que corresponde al año y el idioma
	 * 
	 * @param anio
	 *            int
	 * @param file
	 *            String
	 * @param idioma
	 *            String
	 * @return String
	 */
	public String obtenerNombreFichero(String file, String idioma) {
		String res = "";
		File folder = new File(Aa21bConstantes.DATOSDIR);
		ExcelAa21bFichaExpedienteView.logger
				.info("Obteniendo plantilla correspondiente");
		FiltroNombre fil = new FiltroNombre(file, idioma);
		File[] listOfFiles = folder.listFiles(fil);
		File f = null;

		// String dname = "";
		Arrays.sort(listOfFiles);
		for (int i = 0; i < listOfFiles.length; i++) {
			f = listOfFiles[i];
			// dname = f.getName();
			// dname = f.getName().substring(file.length(), file.length() + 4);
			// fileanio = Integer.parseInt(dname);
			if (i == 0) {
				res = f.getName();
				// break;
			}
		}
		if (res.equals(""))
			res = f.getName();
		return res.substring(0, res.length() - 4);
	}

	/**
	 * Establece la plantilla antes de que comenzar la creación del excel
	 * 
	 * @param model
	 *            Map<String, ?>
	 * @param request
	 *            HttpServletRequest
	 * @param response
	 *            HttpServletResponse
	 * 
	 */
	public void render(Map<String, ?> model, HttpServletRequest request,
			HttpServletResponse response) {
		Locale locale = RequestContextUtils.getLocale(request);
		String file = Aa21bConstantes.EXCELFICHAEXPEDIENTE;
		String idioma = "ES";
		if (!locale.getDisplayLanguage().contains("es")
				&& !locale.getDisplayLanguage().contains("Spanish"))
			idioma = "EU";
		ExcelAa21bFichaExpedienteView.logger.info("buscando plantilla->"
				+ locale.getDisplayLanguage());
		String ff = file.substring(Aa21bConstantes.DATOSDIR.length() + 5,
				file.length());
		String s = "file:" + Aa21bConstantes.DATOSDIR
				+ obtenerNombreFichero(ff, idioma);
		this.setUrl(s);
		try {
			super.render(model, request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Crea el excel
	 * 
	 * @param model
	 *            Map<String, Object>
	 * @param book
	 *            HSSFWorkbook
	 * @param request
	 *            HttpServletRequest
	 * @param response
	 *            HttpServletResponse Exception Exception
	 * @throws Exception
	 *             Exception
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected void buildExcelDocument(Map<String, Object> model,
			HSSFWorkbook book, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		ExcelAa21bFichaExpedienteView.logger.info("Creando fichero");

		Locale locale = RequestContextUtils.getLocale(request);
		String idioma = "ES";
		if (!locale.getDisplayLanguage().contains("es")
				&& !locale.getDisplayLanguage().contains("Spanish"))
			idioma = "EU";
		// rellenamos las hojas dat(d)

		rellenarDAT((Aa21b20s01) model.get("datosExpediente"),
				(List<Aa21b20s01>) model.get("listaExpAsociados"),
				(List<Aa21b25s01>) model.get("documentosExp"),
				(List<NoraProvincia>) model.get("provincias"),
				(List<NoraMunicipio>) model.get("municipios"),
				(List<Aa21b15s01>) model.get("usuarios"),
				(List<Aa21b13s01>) model.get("servicios"),
				(List<Aa21b14s01>) model.get("archivos"),
				(List<Aa21b21s01>) model.get("fasesExp"),
				(List<Aa21b29s01>) model.get("respExp"),
				(List<Aa21b12s01>) model.get("departamento"), book, idioma,
				locale);

		evaluateAllFormulaCells(book);
		ExcelAa21bFichaExpedienteView.logger.info("fin de fichero");
	}

	/**
	 * 
	 * @param datos
	 *            List<Aa21b15s01>
	 * @param book
	 *            HSSFWorkbook
	 */
	private void rellenarDAT(Aa21b20s01 datosExp,
			List<Aa21b20s01> listaExpAsoc, List<Aa21b25s01> documentosExp,
			List<NoraProvincia> provincias, List<NoraMunicipio> municipios,
			List<Aa21b15s01> usuarios, List<Aa21b13s01> servicios,
			List<Aa21b14s01> archivos, List<Aa21b21s01> fases,
			List<Aa21b29s01> responsables, List<Aa21b12s01> departamentos,
			HSSFWorkbook book, String idioma, Locale locale) {
		// TODO Auto-generated method stub
		HSSFSheet sheetal = book.getSheet("Ficha");
		Map<String, HSSFCellStyle> estilos = createStyles(book);

		NoraProvincia provincia = null;
		NoraMunicipio municipio = null;
		Aa21b13s01 servicio = null;
		Aa21b15s01 usuario = null;
		Aa21b12s01 departamento = null;
		Aa21b14s01 archivo = null;
		if (provincias != null)
			provincia = (NoraProvincia) provincias.get(0);
		if (municipios != null)
			municipio = (NoraMunicipio) municipios.get(0);
		if (servicios != null)
			servicio = (Aa21b13s01) servicios.get(0);
		if (usuarios != null && !usuarios.isEmpty())
			usuario = (Aa21b15s01) usuarios.get(0);
		if (departamentos != null)
			departamento = (Aa21b12s01) departamentos.get(0);
		if (archivos != null)
			archivo = (Aa21b14s01) archivos.get(0);

		Iterator<Aa21b21s01> iterFases = fases.iterator();
		Iterator<Aa21b25s01> iterDocumentos = documentosExp.iterator();
		Iterator<Aa21b20s01> iterExpAsoc = listaExpAsoc.iterator();
		Iterator<Aa21b29s01> iterHistorico = responsables.iterator();
		if (datosExp != null) {
			int row = 0;
			// create a cell object reference
			HSSFCell c = null;
			row = 6;
			// Expediente
			CellRangeAddress range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, datosExp.getRefExp());
			row += 2;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, datosExp.getObjeto20());
			row += 2;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			if (departamento != null) {
				if (idioma.equalsIgnoreCase("ES")) {
					setText(c, departamento.getDDepar12());
				} else {
					setText(c, departamento.getEDepar12());
				}
			} else {
				setText(c, "-");
			}

			row += 2;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			if (provincia != null)
				setText(c, provincia.getDsO());
			else
				setText(c, "-");
			range = new CellRangeAddress(row, row, 9, 13);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 9);
			c.setCellStyle(estilos.get("detalle"));
			if (municipio != null)
				setText(c, municipio.getDsO());
			else
				setText(c, "-");
			row = row + 8;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			if (usuario != null)
				setText(c, usuario.getDusu15());
			else
				setText(c, "-");

			row += 2;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			if (idioma.equalsIgnoreCase("ES")) {
				setText(c, servicio.getDServ13());
			} else {
				setText(c, servicio.getEServ13());
			}

			row += 2;

			String fechaApertura = "";
			String fechaCierre = "";
			try {
				SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
				SimpleDateFormat sdf_eu = new SimpleDateFormat("yyyy-MM-dd");

				if (Aa21bConstantes.AA21B_IDIOMA_EUS.equalsIgnoreCase(idioma)) {
					if (datosExp.getFaper20() != null) {
						fechaApertura = sdf_eu.format(datosExp.getFaper20());
					}
					if (datosExp.getFcier20() != null) {
						fechaCierre = sdf_eu.format(datosExp.getFcier20());
					}
				} else {
					if (datosExp.getFaper20() != null) {
						fechaApertura = sdf.format(datosExp.getFaper20());
					}
					if (datosExp.getFcier20() != null) {
						fechaCierre = sdf.format(datosExp.getFcier20());
					}
				}
			} catch (Exception e) {
				logger.error("getXml - Error formateando fecha de apertura y cierre : "
						+ e.toString());
			}

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, fechaApertura);

			range = new CellRangeAddress(row, row, 9, 13);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 9);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, fechaCierre);

			row += 2;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			if (idioma.equalsIgnoreCase("ES")) {
				setText(c, datosExp.getDesta());
			} else {
				setText(c, datosExp.getEesta());
			}

			row += 2;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			if (archivo != null) {
				if (idioma.equalsIgnoreCase("ES")) {
					setText(c, archivo.getDarchi14());
				} else {
					setText(c, archivo.getEarchi14());
				}
			} else {
				setText(c, "-");
			}
			range = new CellRangeAddress(row, row, 9, 13);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 9);
			c.setCellStyle(estilos.get("detalle"));
			row = row + 8;
			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, datosExp.getEimpor20() != null ? datosExp.getEimpor20()
					.toString() : "");
			row += 2;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, datosExp.getEimpora20() != null ? datosExp
					.getEimpora20().toString() : "");

			row += 2;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, datosExp.getObser20());

			row += 2;

			range = new CellRangeAddress(row, row, 3, 7);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 3);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, datosExp.getRefer20());

			row = row + 3;

			// Fases
			sheetal.createRow(row);
			range = new CellRangeAddress(row, row + 1, 1, 13);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 1);
			c.setCellStyle(estilos.get("titulo"));
			setText(c, messageSource.getMessage("fichaExp.fases", null, locale));

			row = crearFases(iterFases, sheetal, range, row, idioma, c,
					estilos, locale);

			row = row + 3;

			// Documentos
			sheetal.createRow(row);
			range = new CellRangeAddress(row, row + 1, 1, 13);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 1);
			c.setCellStyle(estilos.get("titulo"));
			setText(c, messageSource.getMessage("fichaExp.documentos", null,
					locale));

			row = crearDocumentos(iterDocumentos, sheetal, range, row, idioma,
					c, estilos, locale);

			row = row + 3;

			// Expedientes Relacionados
			sheetal.createRow(row);
			range = new CellRangeAddress(row, row + 1, 1, 13);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 1);
			c.setCellStyle(estilos.get("titulo"));
			setText(c, messageSource.getMessage("fichaExp.expAsociados", null,
					locale));

			row = crearExpAsociados(datosExp, iterExpAsoc, sheetal, range, row,
					idioma, c, estilos, locale);

			row = row + 3;

			// Responsables
			sheetal.createRow(row);
			range = new CellRangeAddress(row, row + 1, 1, 13);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 1);
			c.setCellStyle(estilos.get("titulo"));
			setText(c,
					messageSource.getMessage("fichaExp.expResp", null, locale));

			row = crearHistorico(iterHistorico, sheetal, range, row, idioma, c,
					estilos, locale, datosExp.getCrespo20());

			row = row + 4;

		}

	}

	/**
	 * 
	 * @param iterHistorico
	 * @param sheetal
	 * @param range
	 * @param row
	 * @param idioma
	 * @param c
	 * @param estilos
	 * @param locale
	 * @return
	 */
	private int crearHistorico(Iterator<Aa21b29s01> iterHistorico,
			HSSFSheet sheetal, CellRangeAddress range, int row, String idioma,
			HSSFCell c, Map<String, HSSFCellStyle> estilos, Locale locale,
			Long responsableExp) {
		// TODO Auto-generated method stub
		row++;
		row++;
		row++;

		sheetal.createRow(row);
		range = new CellRangeAddress(row, row, 1, 3);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 1);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c, messageSource.getMessage("fichaExp.codigo", null, locale));

		range = new CellRangeAddress(row, row, 4, 9);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 4);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c, messageSource.getMessage("fichaExp.nombre", null, locale));

		range = new CellRangeAddress(row, row, 10, 11);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 10);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c, messageSource.getMessage("fichaExp.fecha", null, locale));

		row++;
		row++;

		Aa21b29s01 responsable = new Aa21b29s01();
		while (iterHistorico.hasNext()) {
			responsable = iterHistorico.next();

			if (responsableExp != responsable.getCrespo29()) {

				sheetal.createRow(row);
				range = new CellRangeAddress(row, row, 1, 3);
				sheetal.addMergedRegion(range);
				c = getCell(sheetal, row, 1);
				c.setCellStyle(estilos.get("detalle"));
				setText(c, responsable.getCrespo29() != null ? responsable
						.getCrespo29().toString() : "");

				range = new CellRangeAddress(row, row, 4, 9);
				sheetal.addMergedRegion(range);
				c = getCell(sheetal, row, 4);
				c.setCellStyle(estilos.get("detalle"));
				setText(c, responsable.getDrespo29());

				String fechaResp = "";
				if (responsable.getFrespo29() != null) {
					try {
						SimpleDateFormat sdf = new SimpleDateFormat(
								"dd-MM-yyyy");
						SimpleDateFormat sdf_eu = new SimpleDateFormat(
								"yyyy-MM-dd");

						if (Aa21bConstantes.AA21B_IDIOMA_EUS
								.equalsIgnoreCase(idioma)) {
							fechaResp = sdf_eu
									.format(responsable.getFrespo29());
						} else {
							fechaResp = sdf.format(responsable.getFrespo29());
						}
					} catch (Exception e) {
						logger.error("getXml - Error formateando fecha responsable exp : "
								+ e.toString());
					}
				}

				range = new CellRangeAddress(row, row, 10, 11);
				sheetal.addMergedRegion(range);
				c = getCell(sheetal, row, 10);
				c.setCellStyle(estilos.get("detalle"));
				setText(c, fechaResp);

				row++;
			}
		}

		return row;
	}

	/**
	 * 
	 * @param iterExpAsoc
	 *            Iterator<Aa21b20s01>
	 * @param sheetal
	 *            HSSFSheet
	 * @param range
	 *            CellRangeAddress
	 * @param row
	 *            int
	 * @param idioma
	 *            String
	 * @param c
	 *            HSSFCell
	 * @param estilos
	 *            Map<String, HSSFCellStyle>
	 * @param locale
	 *            Locale
	 * @return int
	 */
	private int crearExpAsociados(Aa21b20s01 datosExp,
			Iterator<Aa21b20s01> iterExpAsoc, HSSFSheet sheetal,
			CellRangeAddress range, int row, String idioma, HSSFCell c,
			Map<String, HSSFCellStyle> estilos, Locale locale) {
		// TODO Auto-generated method stub
		row++;
		row++;
		row++;

		Aa21b20s01 expAsoc = new Aa21b20s01();
		while (iterExpAsoc.hasNext()) {
			expAsoc = iterExpAsoc.next();
			// 20161019 - INIGO
			if (!expAsoc.getRefExp().equals(datosExp.getRefExp())) {
				sheetal.createRow(row);
				range = new CellRangeAddress(row, row, 1, 3);
				sheetal.addMergedRegion(range);
				c = getCell(sheetal, row, 1);
				c.setCellStyle(estilos.get("detalle"));
				// Angel 09/06/2018 - Añadir también el expediente de baja si
				// existe
				// setText(c, expAsoc.getRefExp());
				StringBuffer expAsociado = new StringBuffer();
				expAsociado.append(expAsoc.getRefExp());
				if (expAsoc.getUbica20() != null) {
					expAsociado.append("(").append(expAsoc.getUbica20())
							.append(")");
				}
				setText(c, expAsociado.toString());
				// Fin Angel
				row++;
			}
		}
		row++;

		return row;
	}

	/**
	 * 
	 * @param iterDocumentos
	 *            Iterator<Aa21b25s01>
	 * @param sheetal
	 *            HSSFSheet
	 * @param range
	 *            CellRangeAddress
	 * @param row
	 *            int
	 * @param idioma
	 *            String
	 * @param c
	 *            HSSFCell
	 * @param estilos
	 *            Map<String, HSSFCellStyle>
	 * @param locale
	 *            Locale
	 * @return int
	 */
	private int crearDocumentos(Iterator<Aa21b25s01> iterDocumentos,
			HSSFSheet sheetal, CellRangeAddress range, int row, String idioma,
			HSSFCell c, Map<String, HSSFCellStyle> estilos, Locale locale) {
		// TODO Auto-generated method stub
		row++;
		row++;
		row++;

		sheetal.createRow(row);
		range = new CellRangeAddress(row, row, 1, 3);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 1);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c, messageSource.getMessage("fichaExp.documento", null, locale));

		range = new CellRangeAddress(row, row, 4, 9);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 4);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c,
				messageSource.getMessage("fichaExp.descripcion", null, locale));

		range = new CellRangeAddress(row, row, 10, 11);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 10);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c,
				messageSource.getMessage("fichaExp.fanotacion", null, locale));

		range = new CellRangeAddress(row, row, 12, 13);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 12);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c,
				messageSource.getMessage("fichaExp.nanotacion", null, locale));

		row++;
		row++;

		Aa21b25s01 documento = new Aa21b25s01();
		while (iterDocumentos.hasNext()) {
			documento = iterDocumentos.next();
			sheetal.createRow(row);
			range = new CellRangeAddress(row, row, 1, 3);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 1);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, documento.getCdocu25() != null ? documento.getCdocu25()
					.toString() : "");

			range = new CellRangeAddress(row, row, 4, 9);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 4);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, documento.getDdocu25());

			String fanotacion = "";
			if (documento.getFanot25() != null) {
				try {
					SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
					SimpleDateFormat sdf_eu = new SimpleDateFormat("yyyy-MM-dd");

					if (Aa21bConstantes.AA21B_IDIOMA_EUS
							.equalsIgnoreCase(idioma)) {
						fanotacion = sdf_eu.format(documento.getFanot25());
					} else {
						fanotacion = sdf.format(documento.getFanot25());
					}
				} catch (Exception e) {
					logger.error("getXml - Error formateando fecha anotacion doc : "
							+ e.toString());
				}
			}

			range = new CellRangeAddress(row, row, 10, 11);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 6);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, fanotacion);

			range = new CellRangeAddress(row, row, 12, 13);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 12);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, documento.getNanot25() != null ? documento.getNanot25()
					.toString() : "");

			row++;

		}

		return row;
	}

	/**
	 * 
	 * @param iterFases
	 *            Iterator<Aa21b21s01>
	 * @param sheetal
	 *            HSSFSheet
	 * @param range
	 *            CellRangeAddress
	 * @param row
	 *            int
	 * @param idioma
	 *            String
	 * @param c
	 *            HSSFCell
	 * @param estilos
	 *            Map<String, HSSFCellStyle>
	 * @param locale
	 *            Locale
	 * 
	 * @return int
	 */
	private int crearFases(Iterator<Aa21b21s01> iterFases, HSSFSheet sheetal,
			CellRangeAddress range, int row, String idioma, HSSFCell c,
			Map<String, HSSFCellStyle> estilos, Locale locale) {
		Aa21b21s01 fase = new Aa21b21s01();

		row++;
		row++;
		row++;

		sheetal.createRow(row);
		range = new CellRangeAddress(row, row, 1, 5);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 1);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c, messageSource.getMessage("fichaExp.fase", null, locale));

		range = new CellRangeAddress(row, row, 6, 8);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 6);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c, messageSource.getMessage("fichaExp.fprevi", null, locale));

		range = new CellRangeAddress(row, row, 9, 11);
		sheetal.addMergedRegion(range);
		c = getCell(sheetal, row, 9);
		c.setCellStyle(estilos.get("cabeceraDetalle"));
		setText(c, messageSource.getMessage("fichaExp.freal", null, locale));

		row++;
		row++;

		while (iterFases.hasNext()) {
			fase = iterFases.next();
			sheetal.createRow(row);
			range = new CellRangeAddress(row, row, 1, 5);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 1);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, fase.getCfase21() != null ? fase.getCfase21().toString()
					: "");

			String fechaPrevista = "";
			String fechaReal = "";

			try {
				SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
				SimpleDateFormat sdf_eu = new SimpleDateFormat("yyyy-MM-dd");

				if (Aa21bConstantes.AA21B_IDIOMA_EUS.equalsIgnoreCase(idioma)) {
					if (fechaPrevista != null) {
						fechaPrevista = sdf_eu.format(fase.getFprevi21());
					}
					if (fechaReal != null) {
						fechaReal = sdf_eu.format(fase.getFreal21());
					}
				} else {
					if (fechaPrevista != null) {
						fechaPrevista = sdf.format(fase.getFprevi21());
					}
					if (fechaReal != null) {
						fechaReal = sdf.format(fase.getFreal21());
					}
				}
			} catch (Exception e) {
				logger.error("getXml - Error formateando fecha prevista y real: "
						+ e.toString());
			}

			range = new CellRangeAddress(row, row, 6, 8);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 6);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, fechaPrevista);

			range = new CellRangeAddress(row, row, 9, 11);
			sheetal.addMergedRegion(range);
			c = getCell(sheetal, row, 9);
			c.setCellStyle(estilos.get("detalle"));
			setText(c, fechaReal);

			row++;

		}
		return row;
	}

	/**
	 * Añade una línea con dos
	 * 
	 * @param sheet
	 *            HSSFSheet
	 * @param row
	 *            int
	 * @param col
	 *            int
	 * @param col1
	 *            String
	 */
	/*
	 * private void setLine(HSSFSheet sheet, int row, int col, String col1) {
	 * HSSFCell c = getCell(sheet, row, col);
	 * 
	 * c.setCellValue(col1);
	 * 
	 * }
	 */

	/**
	 * Method 'Map'
	 * 
	 * @param wb
	 *            HSSFWorkbook
	 * 
	 * @return Map<String, HSSFCellStyle>
	 */
	private static Map<String, HSSFCellStyle> createStyles(HSSFWorkbook wb) {
		Map<String, HSSFCellStyle> styles = new HashMap<String, HSSFCellStyle>();
		// // titulo principal
		HSSFDataFormat dfImporte = wb.createDataFormat();

		HSSFFont fontcabecera = wb.createFont();
		// cabecera tablas
		fontcabecera.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		fontcabecera.setColor(HSSFColor.BLACK.index);
		fontcabecera.setItalic(true);
		fontcabecera.setFontHeightInPoints((short) 12);
		HSSFCellStyle cabecera = wb.createCellStyle();
		cabecera.setFillForegroundColor(HSSFColor.WHITE.index);
		cabecera.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		cabecera.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		cabecera.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		cabecera.setFont(fontcabecera);
		cabecera.setWrapText(true);
		styles.put("cabecera", cabecera);

		HSSFFont fontcabeceraDetalle = wb.createFont();
		// cabecera tablas
		fontcabeceraDetalle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		fontcabeceraDetalle.setColor(HSSFColor.BLACK.index);
		fontcabeceraDetalle.setItalic(true);
		fontcabeceraDetalle.setFontHeightInPoints((short) 12);
		HSSFCellStyle cabeceraDetalle = wb.createCellStyle();
		cabeceraDetalle.setFillForegroundColor(HSSFColor.WHITE.index);
		cabeceraDetalle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		cabeceraDetalle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		cabeceraDetalle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		cabeceraDetalle.setFont(fontcabeceraDetalle);
		cabeceraDetalle.setWrapText(true);
		styles.put("cabeceraDetalle", cabeceraDetalle);

		HSSFFont fontTitulo = wb.createFont();
		// cabecera tablas
		fontTitulo.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		fontTitulo.setColor(HSSFColor.BLACK.index);
		fontTitulo.setFontHeightInPoints((short) 24);
		HSSFCellStyle titulo = wb.createCellStyle();
		titulo.setFillForegroundColor(HSSFColor.WHITE.index);
		titulo.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		titulo.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		titulo.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		titulo.setFont(fontTitulo);
		titulo.setWrapText(true);
		styles.put("titulo", titulo);

		HSSFFont fontcabeceraDesc = wb.createFont();
		// cabecera tablas
		fontcabeceraDesc.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		fontcabeceraDesc.setColor(HSSFColor.BLACK.index);
		fontcabeceraDesc.setItalic(true);
		fontcabeceraDesc.setFontHeightInPoints((short) 12);
		HSSFCellStyle cabeceraDesc = wb.createCellStyle();
		cabeceraDesc.setFillForegroundColor(HSSFColor.WHITE.index);
		cabeceraDesc.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		cabeceraDesc.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		cabeceraDesc.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		cabeceraDesc.setFont(fontcabeceraDesc);
		cabeceraDesc.setWrapText(true);
		styles.put("cabeceraDesc", cabeceraDesc);

		HSSFFont lineaCabeFont = wb.createFont();
		// cabecera tablas
		lineaCabeFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		lineaCabeFont.setColor(HSSFColor.BLACK.index);
		lineaCabeFont.setFontHeightInPoints((short) 8);
		HSSFCellStyle lineaCabe = wb.createCellStyle();
		lineaCabe.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
		lineaCabe.setTopBorderColor(HSSFColor.BLACK.index);
		lineaCabe.setBorderRight(HSSFCellStyle.BORDER_NONE);
		lineaCabe.setBorderLeft(HSSFCellStyle.BORDER_NONE);
		lineaCabe.setBorderBottom(HSSFCellStyle.BORDER_NONE);
		lineaCabe.setFont(lineaCabeFont);

		styles.put("lineaCabecera", lineaCabe);

		HSSFFont fontFiltro = wb.createFont();
		// cabecera tablas
		fontFiltro.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		fontFiltro.setColor(HSSFColor.BLACK.index);
		fontFiltro.setFontHeightInPoints((short) 12);
		HSSFCellStyle filtro = wb.createCellStyle();
		filtro.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		filtro.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		filtro.setFont(fontFiltro);
		filtro.setWrapText(true);
		styles.put("filtro", filtro);

		HSSFFont fontDetalle = wb.createFont();
		// cabecera tablas
		fontDetalle.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		fontDetalle.setColor(HSSFColor.BLACK.index);
		fontDetalle.setFontHeightInPoints((short) 12);
		HSSFCellStyle detalle = wb.createCellStyle();
		detalle.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		detalle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		detalle.setFont(fontDetalle);
		detalle.setWrapText(true);
		styles.put("detalle", detalle);

		HSSFFont fontFiltroDesc = wb.createFont();
		// cabecera tablas
		fontFiltroDesc.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		fontFiltroDesc.setColor(HSSFColor.BLACK.index);
		fontFiltroDesc.setItalic(true);
		fontFiltroDesc.setFontHeightInPoints((short) 12);
		HSSFCellStyle filtroDesc = wb.createCellStyle();
		filtroDesc.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		filtroDesc.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		filtroDesc.setFont(fontFiltroDesc);
		filtroDesc.setWrapText(true);
		styles.put("filtroDesc", filtro);

		HSSFCellStyle propdat = wb.createCellStyle();
		propdat.cloneStyleFrom(cabecera);
		propdat.setBorderRight(HSSFCellStyle.BORDER_THIN);
		propdat.setRightBorderColor(HSSFColor.GREY_50_PERCENT.index);
		propdat.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		propdat.setLeftBorderColor(HSSFColor.GREY_50_PERCENT.index);
		propdat.setBorderTop(HSSFCellStyle.BORDER_THIN);
		propdat.setTopBorderColor(HSSFColor.GREY_50_PERCENT.index);
		propdat.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		propdat.setBottomBorderColor(HSSFColor.GREY_50_PERCENT.index);
		propdat.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
		styles.put("cabecera2", propdat);
		HSSFFont fontter = wb.createFont();
		// cabecera tablas
		fontter.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		fontter.setColor(HSSFColor.WHITE.index);
		fontter.setFontHeightInPoints((short) 10);
		//
		// // datos
		HSSFFont fontdatos = wb.createFont();
		fontdatos.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		fontdatos.setColor(HSSFColor.BLACK.index);
		fontdatos.setFontHeightInPoints((short) 8);
		fontdatos.setFontName("Times New Roman");
		HSSFCellStyle datos = wb.createCellStyle();
		datos.setFillForegroundColor(HSSFColor.WHITE.index);
		datos.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		datos.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
		datos.setFont(fontdatos);
		datos.setWrapText(true);
		datos.setBorderRight(HSSFCellStyle.BORDER_THIN);
		datos.setRightBorderColor(HSSFColor.GREY_50_PERCENT.index);
		datos.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		datos.setLeftBorderColor(HSSFColor.GREY_50_PERCENT.index);
		datos.setBorderTop(HSSFCellStyle.BORDER_THIN);
		datos.setTopBorderColor(HSSFColor.GREY_50_PERCENT.index);
		datos.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		datos.setBottomBorderColor(HSSFColor.GREY_50_PERCENT.index);
		datos.setDataFormat(dfImporte.getFormat("#,##0"));
		styles.put("datos", datos);
		//
		HSSFCellStyle suma = wb.createCellStyle();
		suma.cloneStyleFrom(datos);
		suma.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
		suma.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index);
		suma.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		styles.put("datossuma", suma);

		HSSFCellStyle porcentaje = wb.createCellStyle();
		porcentaje.cloneStyleFrom(datos);
		porcentaje.setDataFormat(dfImporte.getFormat("#,##0.0"));
		styles.put("datosporcentaje", porcentaje);
		//
		HSSFCellStyle porcentajesuma = wb.createCellStyle();
		porcentajesuma.cloneStyleFrom(porcentaje);
		porcentajesuma.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index);
		porcentajesuma.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		styles.put("datosporcentajesuma", porcentajesuma);
		//
		// // Años y meses (negrita y centrado)
		HSSFFont font = wb.createFont();
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		font.setColor(HSSFColor.BLACK.index);
		font.setFontHeightInPoints((short) 8);
		font.setFontName("Times New Roman");
		HSSFCellStyle bold = wb.createCellStyle();
		bold.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		bold.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		bold.setFont(font);
		//
		styles.put("negrita", bold);
		//
		HSSFCellStyle boldcoma1lima = wb.createCellStyle();
		boldcoma1lima.cloneStyleFrom(datos);
		boldcoma1lima.setDataFormat(dfImporte.getFormat("#,##0"));
		boldcoma1lima.setFillForegroundColor(HSSFColor.LIME.index);
		boldcoma1lima.setFont(font);
		styles.put("formatlima", boldcoma1lima);
		//
		HSSFCellStyle boldcoma1 = wb.createCellStyle();
		boldcoma1.cloneStyleFrom(bold);
		boldcoma1.setDataFormat(dfImporte.getFormat("#,##0"));
		styles.put("negritaformat", boldcoma1);
		//
		HSSFCellStyle boldcoma = wb.createCellStyle();
		boldcoma.cloneStyleFrom(bold);
		boldcoma.setDataFormat(dfImporte.getFormat("#,##0.0"));
		styles.put("negritacoma", boldcoma);
		//
		HSSFCellStyle boldcomalima = wb.createCellStyle();
		boldcomalima.cloneStyleFrom(datos);
		boldcomalima.setDataFormat(dfImporte.getFormat("#,##0.0"));
		boldcomalima.setFillForegroundColor(HSSFColor.LIME.index);
		boldcomalima.setFont(font);
		styles.put("comalima", boldcomalima);
		//
		HSSFCellStyle hiddenstyle = wb.createCellStyle();
		hiddenstyle.setHidden(true);
		styles.put("oculta", bold);
		return styles;
	}

}
