package com.ejie.ab79.service.preguntasRespuestas;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.activation.MimetypesFileTypeMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ejie.ab79.comun.Constantes;
import com.ejie.ab79.dao.preguntasRespuestas.FicherosAdjProDao;
import com.ejie.ab79.dao.preguntasRespuestas.OpcionesPreExpDao;
import com.ejie.ab79.dao.preguntasRespuestas.OpcionesPreProDao;
import com.ejie.ab79.dao.preguntasRespuestas.PreguntasExpedienteDao;
import com.ejie.ab79.dao.preguntasRespuestas.PreguntasProtocoloDao;
import com.ejie.ab79.model.inspecciones.Inspecciones;
import com.ejie.ab79.model.preguntasRespuestas.FicherosAdjPro;
import com.ejie.ab79.model.preguntasRespuestas.ListaPreguntasRespuestas;
import com.ejie.ab79.model.preguntasRespuestas.OpcionesPreExp;
import com.ejie.ab79.model.preguntasRespuestas.OpcionesPrePro;
import com.ejie.ab79.model.preguntasRespuestas.PreguntasExpediente;
import com.ejie.ab79.model.preguntasRespuestas.PreguntasProtocolo;
import com.ejie.ab79.model.preguntasRespuestas.PreguntasRespuestasExpediente;
import com.ejie.ab79.model.preguntasRespuestas.PreguntasRespuestasProtocolo;
import com.ejie.ab79.model.preguntasRespuestas.RelProPre;
import com.ejie.ab79.model.preguntasRespuestas.RespuestasExpediente;
import com.ejie.ab79.model.preguntasRespuestas.RespuestasProtocolo;
import com.ejie.ab79.model.protocolos.Protocolos;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * PreguntasProtocoloServiceImpl  
 * 
 *  
 */

@Service(value = "preguntasProtocoloService")
public class PreguntasProtocoloServiceImpl implements PreguntasProtocoloService {

	private static final Logger logger = LoggerFactory.getLogger(PreguntasProtocoloServiceImpl.class);

	@Autowired
	private PreguntasProtocoloDao preguntasProtocoloDao;

	@Autowired
	private FicherosAdjProDao ficherosAdjProDao;

	@Autowired
	private OpcionesPreProDao opcionesPreProDao;

	@Autowired
	private RespuestasProtocoloService respuestasProtocoloService;

	@Autowired
	private PreguntasExpedienteService preguntasExpedienteService;

	@Autowired
	private RespuestasExpedienteService respuestasExpedienteService;

	@Autowired
	private PreguntasExpedienteDao preguntasExpedienteDao;

	@Autowired
	private OpcionesPreExpDao opcionesPreExpDao;

	@Resource
	private ReloadableResourceBundleMessageSource appMessageSource;

	/**
	 * Inserts a single row in the PreguntasProtocolo table.
	 *
	 * @param preguntasProtocolo
	 *            PreguntasProtocolo
	 * @return PreguntasProtocolo
	 */
	@Transactional(rollbackFor = Throwable.class)
	public PreguntasProtocolo add(PreguntasProtocolo preguntasProtocolo) {
		return this.preguntasProtocoloDao.add(preguntasProtocolo);
	}

	/**
	 * Añade una pregunta a AB7911T00 y a la relación AB7919T00
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public PreguntasProtocolo addPreguntaRelacion(PreguntasProtocolo preguntaProtocolo, RelProPre relProPre) {

		PreguntasProtocoloServiceImpl.logger.info("Insertamos pregunta en AB7911T00");
		PreguntasProtocolo preguntaProtocoloAux = this.preguntasProtocoloDao.add(preguntaProtocolo);

		if (preguntaProtocolo.getOpcionesEs() != null && preguntaProtocolo.getOpcionesEu() != null) {

			String[] opcionesEs = preguntaProtocolo.getOpcionesEs().replace(" ", "").split(";");
			String[] opcionesEu = preguntaProtocolo.getOpcionesEu().replace(" ", "").split(";");
			List<OpcionesPrePro> listaOpciones = new ArrayList<OpcionesPrePro>();

			PreguntasProtocoloServiceImpl.logger.info("Insertamos opcionesPrePro en AB7917T00");
			for (int i = 0; i < opcionesEs.length; i++) {
				OpcionesPrePro opcionesPrePro = new OpcionesPrePro();
				opcionesPrePro.setIdPreguntaProtocolo(preguntaProtocoloAux.getIdPreguntaProtocolo());
				opcionesPrePro.setDescripcionCastellano(opcionesEs[i]);
				opcionesPrePro.setDescripcionEuskera(opcionesEu[i]);
				opcionesPrePro.setFechaRegistro(preguntaProtocoloAux.getFechaRegistro());
				opcionesPrePro.setUsuarioRegistro(preguntaProtocoloAux.getUsuarioRegistro());
				this.opcionesPreProDao.add(opcionesPrePro);
				listaOpciones.add(opcionesPrePro);
			}

			preguntaProtocoloAux.setOpcionesPrePro(listaOpciones);

		}

		relProPre.setIdPreguntaProtocolo(preguntaProtocoloAux.getIdPreguntaProtocolo());

		PreguntasProtocoloServiceImpl.logger.info("Insertamos la relación en AB7919T00");
		// Insertamos la relación de la pregunta insertada con el protocolo.
		this.preguntasProtocoloDao.insertRelProPre(relProPre);

		return preguntaProtocoloAux;
	}

	@Override
	public PreguntasProtocolo updatePreguntaOpciones(PreguntasProtocolo preguntaProtocolo) {

		PreguntasProtocolo preguntaProtocoloAux = this.preguntasProtocoloDao.update(preguntaProtocolo);

		if (preguntaProtocolo.getOpcionesEs() != null && preguntaProtocolo.getOpcionesEu() != null) {

			String[] opcionesEs = preguntaProtocolo.getOpcionesEs().replace(" ", "").split(";");
			String[] opcionesEu = preguntaProtocolo.getOpcionesEu().replace(" ", "").split(";");
			List<OpcionesPrePro> listaOpcionesPregunta = new ArrayList<OpcionesPrePro>();

			this.opcionesPreProDao.removeByPregunta(preguntaProtocolo);

			for (int i = 0; i < opcionesEs.length; i++) {
				OpcionesPrePro opcionesPrePro = new OpcionesPrePro();
				opcionesPrePro.setIdPreguntaProtocolo(preguntaProtocoloAux.getIdPreguntaProtocolo());
				opcionesPrePro.setDescripcionCastellano(opcionesEs[i]);
				opcionesPrePro.setDescripcionEuskera(opcionesEu[i]);
				opcionesPrePro.setFechaRegistro(preguntaProtocolo.getFechaRegistro());
				opcionesPrePro.setUsuarioRegistro(preguntaProtocolo.getUsuarioRegistro());
				this.opcionesPreProDao.add(opcionesPrePro);
				listaOpcionesPregunta.add(opcionesPrePro);
			}

			preguntaProtocoloAux.setOpcionesPrePro(listaOpcionesPregunta);

		}

		return preguntaProtocoloAux;
	}

	/**
	 * Updates a single row in the PreguntasProtocolo table.
	 *
	 * @param preguntasProtocolo
	 *            PreguntasProtocolo
	 * @return PreguntasProtocolo
	 */
	@Transactional(rollbackFor = Throwable.class)
	public PreguntasProtocolo update(PreguntasProtocolo preguntasProtocolo) {
		return this.preguntasProtocoloDao.update(preguntasProtocolo);
	}

	/**
	 * Finds a single row in the PreguntasProtocolo table.
	 *
	 * @param preguntasProtocolo
	 *            PreguntasProtocolo
	 * @return PreguntasProtocolo
	 */
	public PreguntasProtocolo find(PreguntasProtocolo preguntasProtocolo) {
		return this.preguntasProtocoloDao.find(preguntasProtocolo);
	}

	/**
	 * Deletes a single row in the PreguntasProtocolo table.
	 *
	 * @param preguntasProtocolo
	 *            PreguntasProtocolo
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void remove(PreguntasProtocolo preguntasProtocolo) {
		this.preguntasProtocoloDao.remove(preguntasProtocolo);
	}

	/**
	 * Buscamos la linea correspondiente al identificador del dato del
	 * establecimiento
	 *
	 * @param preguntasprotocolo
	 *            PreguntasProtocolo
	 *
	 * @return PreguntasProtocolo
	 */

	@Override
	public PreguntasProtocolo findLineaPregunta(PreguntasProtocolo preguntasProtocolo) {
		return this.preguntasProtocoloDao.findLineaPregunta(preguntasProtocolo);
	}

	/**
	 * Finds a list of rows in the PreguntasProtocolo table.
	 *
	 * @param preguntasProtocolo
	 *            PreguntasProtocolo
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @return List<PreguntasProtocolo>
	 */
	public List<PreguntasProtocolo> findAll(PreguntasProtocolo preguntasProtocolo, TableRequestDto tableRequestDto) {
		return this.preguntasProtocoloDao.findAll(preguntasProtocolo, tableRequestDto);
	}

	/**
	 * Finds rows in the PreguntasProtocolo table using like.
	 *
	 * @param preguntasProtocolo
	 *            PreguntasProtocolo
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<PreguntasProtocolo>
	 */
	public List<PreguntasProtocolo> findAllLike(PreguntasProtocolo preguntasProtocolo, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.preguntasProtocoloDao.findAllLike(preguntasProtocolo, tableRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the PreguntasProtocolo table.
	 *
	 * @param filterPreguntasProtocolo
	 *            PreguntasProtocolo
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 */
	public void removeMultiple(PreguntasProtocolo filterPreguntasProtocolo, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		this.preguntasProtocoloDao.removeMultiple(filterPreguntasProtocolo, tableRequestDto, startsWith);
	}

	/**
	 * Filter method in the PreguntasProtocolo table.
	 *
	 * @param filterPreguntasProtocolo
	 *            PreguntasProtocolo
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return TableResponseDto<PreguntasProtocolo>
	 */
	public TableResponseDto<PreguntasProtocolo> filter(PreguntasProtocolo filterPreguntasProtocolo,
			TableRequestDto tableRequestDto, Boolean startsWith) {

		List<PreguntasProtocolo> listaPreguntasProtocolo = new ArrayList<PreguntasProtocolo>();

		if (filterPreguntasProtocolo.getIdProtocolo() != null) {
			tableRequestDto.setSidx("ORDEN");
			listaPreguntasProtocolo = this.preguntasProtocoloDao.findByProtocolo(filterPreguntasProtocolo,
					tableRequestDto, false);
			List<OpcionesPrePro> opciones = this.preguntasProtocoloDao.findOpcionesPrePro();

			for (PreguntasProtocolo preguntaProtocolo : listaPreguntasProtocolo) {
				if (preguntaProtocolo.getIdTipoPregunta() == Constantes.TIPO_PREGUNTA_CHECKBOX) {
					String stringOpciones = "";

					for (OpcionesPrePro opcion : opciones) {
						if (preguntaProtocolo.getIdPreguntaProtocolo().equals(opcion.getIdPreguntaProtocolo())) {
							if (LocaleContextHolder.getLocale().toString().equals(Constantes.CASTELLANO)) {
								stringOpciones += opcion.getDescripcionCastellano() + "; ";
							} else if (LocaleContextHolder.getLocale().toString().equals(Constantes.EUSKERA)) {
								stringOpciones += opcion.getDescripcionEuskera() + "; ";
							}

						}
					}

					if (stringOpciones.length() > 0) {
						stringOpciones = stringOpciones.substring(0, stringOpciones.length() - 2);
					}

					preguntaProtocolo.setOpciones(stringOpciones);
				}

				preguntaProtocolo.setNumeroRespuestas(
						this.preguntasProtocoloDao.calcularNumeroRespuestasRelacion(preguntaProtocolo));

			}

			Long recordNum = this.preguntasProtocoloDao.findAllLikeCountRelProPre(
					filterPreguntasProtocolo != null ? filterPreguntasProtocolo : new PreguntasProtocolo(), false);

			TableResponseDto<PreguntasProtocolo> usuarioDto = new TableResponseDto<PreguntasProtocolo>(tableRequestDto,
					recordNum, listaPreguntasProtocolo);

			if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
				List<TableRowDto<PreguntasProtocolo>> reorderSelection = this.preguntasProtocoloDao
						.reorderSelectionRelProPre(filterPreguntasProtocolo, tableRequestDto, startsWith);
				usuarioDto.setReorderedSelection(reorderSelection);
				usuarioDto.addAdditionalParam("reorderedSelection", reorderSelection);
				usuarioDto.addAdditionalParam("selectedAll", tableRequestDto.getMultiselection().getSelectedAll());
			}
			if (tableRequestDto.getSeeker().getSelectedIds() != null) {
				tableRequestDto.setMultiselection(tableRequestDto.getSeeker());
				List<TableRowDto<PreguntasProtocolo>> reorderSeeker = this.preguntasProtocoloDao
						.reorderSelectionRelProPre(filterPreguntasProtocolo, tableRequestDto, startsWith);
				usuarioDto.setReorderedSeeker(reorderSeeker);
				usuarioDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
			}
			return usuarioDto;

		} else {
			tableRequestDto.setSidx("IDPREGUNTAPROTOCOLO");
			listaPreguntasProtocolo = this.preguntasProtocoloDao.findAllLike(filterPreguntasProtocolo, tableRequestDto,
					false);
			List<OpcionesPrePro> opciones = this.preguntasProtocoloDao.findOpcionesPrePro();

			for (PreguntasProtocolo preguntaProtocolo : listaPreguntasProtocolo) {
				if (preguntaProtocolo.getIdTipoPregunta() == Constantes.TIPO_PREGUNTA_CHECKBOX) {
					String stringOpciones = "";

					for (OpcionesPrePro opcion : opciones) {
						if (preguntaProtocolo.getIdPreguntaProtocolo().equals(opcion.getIdPreguntaProtocolo())) {
							if (LocaleContextHolder.getLocale().toString().equals(Constantes.CASTELLANO)) {
								stringOpciones += opcion.getDescripcionCastellano() + "; ";
							} else if (LocaleContextHolder.getLocale().toString().equals(Constantes.EUSKERA)) {
								stringOpciones += opcion.getDescripcionEuskera() + "; ";
							}

						}
					}

					if (stringOpciones.length() > 0) {
						stringOpciones = stringOpciones.substring(0, stringOpciones.length() - 2);
					}

					preguntaProtocolo.setOpciones(stringOpciones);
				}

				if (preguntaProtocolo.getPreguntaValidar() != Constantes.VALIDAR) {
					preguntaProtocolo.setNumeroRespuestas(
							this.preguntasProtocoloDao.calcularNumeroRespuestasPregunta(preguntaProtocolo));
				} else {
					preguntaProtocolo.setNumeroRespuestas(
							this.preguntasProtocoloDao.calcularNumeroRespuestasValidar(preguntaProtocolo));
				}

			}

			Long recordNum = this.preguntasProtocoloDao.findAllLikeCount(
					filterPreguntasProtocolo != null ? filterPreguntasProtocolo : new PreguntasProtocolo(), false);

			TableResponseDto<PreguntasProtocolo> usuarioDto = new TableResponseDto<PreguntasProtocolo>(tableRequestDto,
					recordNum, listaPreguntasProtocolo);

			if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
				List<TableRowDto<PreguntasProtocolo>> reorderSelection = this.preguntasProtocoloDao
						.reorderSelection(filterPreguntasProtocolo, tableRequestDto, startsWith);
				usuarioDto.setReorderedSelection(reorderSelection);
				usuarioDto.addAdditionalParam("reorderedSelection", reorderSelection);
				usuarioDto.addAdditionalParam("selectedAll", tableRequestDto.getMultiselection().getSelectedAll());
			}
			if (tableRequestDto.getSeeker().getSelectedIds() != null) {
				tableRequestDto.setMultiselection(tableRequestDto.getSeeker());
				List<TableRowDto<PreguntasProtocolo>> reorderSeeker = this.preguntasProtocoloDao
						.reorderSelection(filterPreguntasProtocolo, tableRequestDto, startsWith);
				usuarioDto.setReorderedSeeker(reorderSeeker);
				usuarioDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
			}
			return usuarioDto;
		}

	}

	/**
	 * Searches rows in the PreguntasProtocolo table.
	 *
	 * @param filterPreguntasProtocolo
	 *            PreguntasProtocolo
	 * @param searchPreguntasProtocolo
	 *            PreguntasProtocolo
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<PreguntasProtocolo>>
	 */
	public List<TableRowDto<PreguntasProtocolo>> search(PreguntasProtocolo filterPreguntasProtocolo,
			PreguntasProtocolo searchPreguntasProtocolo, TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.preguntasProtocoloDao.search(filterPreguntasProtocolo, searchPreguntasProtocolo, tableRequestDto,
				startsWith);
	}

	/**
	 * Reorder the selection made in PreguntasProtocolo table.
	 *
	 * @param filterPreguntasProtocolo
	 *            PreguntasProtocolo
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return Object
	 */
	public Object reorderSelection(PreguntasProtocolo filterPreguntasProtocolo, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.preguntasProtocoloDao.reorderSelection(filterPreguntasProtocolo, tableRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */

	/**
	 * Finder method in the hierarchical the PreguntasProtocolo table.
	 *
	 * @param filterPreguntasProtocolo
	 *            PreguntasProtocolo
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return TableResponseDto<JerarquiaDto<PreguntasProtocolo>>
	 */
	public TableResponseDto<JerarquiaDto<PreguntasProtocolo>> jerarquia(PreguntasProtocolo filterPreguntasProtocolo,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<JerarquiaDto<PreguntasProtocolo>> listaPreguntasProtocolo = this.preguntasProtocoloDao
				.findAllLikeJerarquia(filterPreguntasProtocolo, tableRequestDto);
		Long recordNum = this.preguntasProtocoloDao.findAllLikeCountJerarquia(filterPreguntasProtocolo,
				tableRequestDto);
		return new TableResponseDto<JerarquiaDto<PreguntasProtocolo>>(tableRequestDto, recordNum,
				listaPreguntasProtocolo);
	}

	/**
	 * Finder method for siblings rows in the hierarchical the
	 * PreguntasProtocolo table.
	 *
	 * @param filterPreguntasProtocolo
	 *            PreguntasProtocolo
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @return TableResponseDto<JerarquiaDto<PreguntasProtocolo>>
	 */
	public TableResponseDto<JerarquiaDto<PreguntasProtocolo>> jerarquiaChildren(
			PreguntasProtocolo filterPreguntasProtocolo, TableRequestDto tableRequestDto) {
		TableResponseDto<JerarquiaDto<PreguntasProtocolo>> tableResponseDto = new TableResponseDto<JerarquiaDto<PreguntasProtocolo>>();
		tableResponseDto.addAdditionalParam(TableResponseDto.CHILDREN,
				this.preguntasProtocoloDao.findAllChild(filterPreguntasProtocolo, tableRequestDto));
		return tableResponseDto;
	}

	/**
	 * Exporta Datos al clipBoard
	 *
	 */
	public List<PreguntasProtocolo> getMultiple(PreguntasProtocolo filterPreguntasProtocolo,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.preguntasProtocoloDao.getMultiple(filterPreguntasProtocolo, tableRequestDto, startsWith);
	}

	@Override
	public List<PreguntasProtocolo> findPreguntasProtocolo(Inspecciones inspeccion) {
		return this.preguntasProtocoloDao.findPreguntasProtocolo(inspeccion);
	}

	@Override
	public List<OpcionesPrePro> findOpcionesPrePro() {
		return this.preguntasProtocoloDao.findOpcionesPrePro();
	}

	@Override
	public List<PreguntasRespuestasProtocolo> findPreguntasRespuestasProtocolo(Inspecciones inspeccion) {

		List<PreguntasRespuestasProtocolo> preguntasRespuestasProtocolo = this.preguntasProtocoloDao
				.findPreguntasRespuestasProtocolo(inspeccion);
		List<OpcionesPrePro> opcionesPrePro = this.preguntasProtocoloDao.findOpcionesPrePro();
		List<FicherosAdjPro> ficherosAdjPro = this.ficherosAdjProDao.findFicheros();

		for (PreguntasRespuestasProtocolo preguntaRespuesta : preguntasRespuestasProtocolo) {
			preguntaRespuesta.getPreguntasProtocolo().setOpcionesPrePro(opcionesPrePro);
			preguntaRespuesta.getRespuestasProtocolo().setFicherosAdjPro(ficherosAdjPro);
		}

		return preguntasRespuestasProtocolo;
	}

	/**
	 * Método que genera una hoja de Excel con las preguntas de
	 * protocolo/expediente del informe técnico.
	 * 
	 */
	@Override
	public void getExcel(Integer idInspeccion, HttpServletResponse response, String identificadorInspeccion,
			String folderNumber, String titulo) {

		Inspecciones inspeccion = new Inspecciones();
		Locale locale = LocaleContextHolder.getLocale();

		boolean castellano = false;
		boolean euskera = false;
		int rowCount;

		// Configuramos variables de idioma.
		if (locale.toString().equals(Constantes.CASTELLANO)) {
			castellano = true;
		} else if (locale.toString().equals(Constantes.EUSKERA)) {
			euskera = true;
		}

		try {

			inspeccion.setIdInspeccion(idInspeccion);
			List<PreguntasRespuestasProtocolo> preguntasRespuestasProtocolo = this.preguntasProtocoloDao
					.findPreguntasRespuestasProtocolo(inspeccion);
			List<PreguntasRespuestasExpediente> preguntasRespuestasValidar = this.preguntasExpedienteService
					.findPreguntasRespuestasValidar(inspeccion);
			List<PreguntasRespuestasExpediente> preguntasRespuestasExpediente = this.preguntasExpedienteService
					.findPreguntasRespuestasExpediente(inspeccion);
			List<OpcionesPrePro> opcionesPrePro = this.preguntasProtocoloDao.findOpcionesPrePro();
			List<OpcionesPreExp> opcionesPreExp = this.preguntasExpedienteDao.findOpcionesPreExp();

			// Nombre del archivo
			String fileName = identificadorInspeccion + Constantes.EXTENSION_EXCEL;

			// Creamos la hoja
			HSSFWorkbook workbook = new HSSFWorkbook();
			HSSFSheet sheet = workbook
					.createSheet(appMessageSource.getMessage("excel.informeTecnico.sheetName", null, locale));

			sheet.protectSheet(Constantes.PASSWORD_EXCEL);

			// Definimos los estilos y fuentes de la hoja
			HSSFFont headerFont = workbook.createFont();
			headerFont.setFontName(HSSFFont.FONT_ARIAL);
			headerFont.setFontHeightInPoints((short) 12);
			headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);

			HSSFFont inspeccionFont = workbook.createFont();
			inspeccionFont.setBoldweight(Font.BOLDWEIGHT_BOLD);

			HSSFCellStyle headerStyle = workbook.createCellStyle();
			headerStyle.setBorderBottom(CellStyle.BORDER_MEDIUM);
			headerStyle.setBorderTop(CellStyle.BORDER_MEDIUM);
			headerStyle.setBorderLeft(CellStyle.BORDER_MEDIUM);
			headerStyle.setBorderRight(CellStyle.BORDER_MEDIUM);
			headerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
			headerStyle.setFont(headerFont);

			HSSFCellStyle objEstablecimientoStyle = workbook.createCellStyle();
			objEstablecimientoStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
			objEstablecimientoStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
			objEstablecimientoStyle.setFont(headerFont);

			HSSFCellStyle inspeccionStyle = workbook.createCellStyle();
			inspeccionStyle.setFont(inspeccionFont);
			inspeccionStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

			HSSFCellStyle disabledStyle = workbook.createCellStyle();
			disabledStyle.setFillPattern(CellStyle.THIN_FORWARD_DIAG);

			HSSFCellStyle preguntaStyle = workbook.createCellStyle();
			preguntaStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

			HSSFCellStyle respuestaStyle = workbook.createCellStyle();
			respuestaStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
			respuestaStyle.setLocked(false);

			// Creamos la fila cabecera de inspección, expediente y título
			HSSFRow rowHeadInspeccion = sheet.createRow(0);
			rowHeadInspeccion.createCell(0)
					.setCellValue(appMessageSource.getMessage("excel.informeTecnico.inspeccion", null, locale));
			rowHeadInspeccion.createCell(1)
					.setCellValue(appMessageSource.getMessage("excel.informeTecnico.expediente", null, locale));
			rowHeadInspeccion.createCell(2)
					.setCellValue(appMessageSource.getMessage("excel.informeTecnico.titulo", null, locale));

			// Creamos la fila con los datos de inspección, expediente y título
			HSSFRow rowInspeccion = sheet.createRow(1);
			rowInspeccion.createCell(0).setCellValue(identificadorInspeccion);
			rowInspeccion.createCell(1).setCellValue(folderNumber);
			rowInspeccion.createCell(2).setCellValue(titulo);

			// Creamos la fila de las preguntas a validar
			if (preguntasRespuestasValidar.size() > 0) {
				HSSFRow rowHeadValidar = sheet.createRow(2);
				rowHeadValidar.createCell(0).setCellValue(
						appMessageSource.getMessage("excel.informeTecnico.preguntasValidar", null, locale));
				rowHeadValidar.createCell(1)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.tipoPreguntas", null, locale));
				rowHeadValidar.createCell(2)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.verificado", null, locale));
				rowHeadValidar.createCell(3)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.declarado", null, locale));
				rowHeadValidar.getCell(0).setCellStyle(headerStyle);
				rowHeadValidar.getCell(1).setCellStyle(headerStyle);
				rowHeadValidar.getCell(2).setCellStyle(headerStyle);
				rowHeadValidar.getCell(3).setCellStyle(headerStyle);
				rowHeadValidar.setHeightInPoints(20);
				rowCount = 3;
			} else {
				rowCount = 2;
			}

			String objEstablecimientoAgrupar = "";

			for (PreguntasRespuestasExpediente preguntaRespuestaValidar : preguntasRespuestasValidar) {
				HSSFRow preguntaValidarRow = sheet.createRow(rowCount++);

				if (preguntaRespuestaValidar.getPreguntasExpediente().getIdentObjEstablecimiento() != null) {
					if (objEstablecimientoAgrupar
							.equals(preguntaRespuestaValidar.getPreguntasExpediente().getIdentObjEstablecimiento())) {
						preguntaRespuestaValidar.getPreguntasExpediente().setIdentObjEstablecimiento(null);
					} else {
						objEstablecimientoAgrupar = preguntaRespuestaValidar.getPreguntasExpediente()
								.getIdentObjEstablecimiento();
					}
				}
				if (preguntaRespuestaValidar.getPreguntasExpediente().getIdentObjEstablecimiento() != null) {
					preguntaValidarRow.createCell(0).setCellValue(
							preguntaRespuestaValidar.getPreguntasExpediente().getDescrObjEstablecimiento());
					preguntaValidarRow.getCell(0).setCellStyle(objEstablecimientoStyle);
					preguntaValidarRow.setHeightInPoints(20);
					sheet.addMergedRegion(
							new CellRangeAddress(preguntaValidarRow.getRowNum(), preguntaValidarRow.getRowNum(), 0, 3));
					preguntaValidarRow = sheet.createRow(rowCount++);
				}

				if (castellano) {
					preguntaValidarRow.createCell(0)
							.setCellValue(preguntaRespuestaValidar.getPreguntasExpediente().getDescripcionCastellano());
				} else if (euskera) {
					preguntaValidarRow.createCell(0)
							.setCellValue(preguntaRespuestaValidar.getPreguntasExpediente().getDescripcionEuskera());
				}

				switch (preguntaRespuestaValidar.getPreguntasExpediente().getIdTipoPregunta()) {
				case Constantes.TIPO_PREGUNTA_NUMERICO:
					preguntaValidarRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTencico.numero", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_FECHA:
					preguntaValidarRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.fecha", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_TEXTO_LIBRE:
					preguntaValidarRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.texto", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_SINO:
					preguntaValidarRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.siNo", null, locale));
					break;
				default:
					break;
				}

				if (preguntaRespuestaValidar.getRespuestasExpediente() != null
						&& preguntaRespuestaValidar.getRespuestasExpediente().getRespuesta() != null) {
					preguntaValidarRow.createCell(2)
							.setCellValue(preguntaRespuestaValidar.getRespuestasExpediente().getRespuesta());
				} else {
					preguntaValidarRow.createCell(2).setCellValue("");
				}

				preguntaValidarRow.createCell(3)
						.setCellValue(preguntaRespuestaValidar.getPreguntasExpediente().getValorValidar());

				preguntaValidarRow.createCell(4)
						.setCellValue(preguntaRespuestaValidar.getPreguntasExpediente().getIdPreguntaExpediente());
				preguntaValidarRow.createCell(6)
						.setCellValue(preguntaRespuestaValidar.getPreguntasExpediente().getIdTipoPregunta());
				preguntaValidarRow.getCell(0).setCellStyle(preguntaStyle);
				preguntaValidarRow.getCell(1).setCellStyle(preguntaStyle);
				preguntaValidarRow.getCell(2).setCellStyle(respuestaStyle);
				preguntaValidarRow.getCell(3).setCellStyle(preguntaStyle);
				preguntaValidarRow.setHeightInPoints(20);

			}

			// Creamos la fila cabecera de las preguntas de protocolo
			if (preguntasRespuestasProtocolo.size() > 0) {
				HSSFRow rowHeadPreguntasProtocolo = sheet.createRow(rowCount);
				rowHeadPreguntasProtocolo.createCell(0).setCellValue(
						appMessageSource.getMessage("excel.informeTecnico.preguntasProtocolo", null, locale));
				rowHeadPreguntasProtocolo.createCell(1)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.tipoPreguntas", null, locale));
				rowHeadPreguntasProtocolo.createCell(2)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.respuestas", null, locale));
				if (!opcionesPrePro.isEmpty()) {
					rowHeadPreguntasProtocolo.createCell(3)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.opciones", null, locale));
				}
				rowHeadPreguntasProtocolo.getCell(0).setCellStyle(headerStyle);
				rowHeadPreguntasProtocolo.getCell(1).setCellStyle(headerStyle);
				rowHeadPreguntasProtocolo.getCell(2).setCellStyle(headerStyle);
				if (!opcionesPrePro.isEmpty()) {
					rowHeadPreguntasProtocolo.getCell(3).setCellStyle(headerStyle);
				}
				rowHeadPreguntasProtocolo.setHeightInPoints(20);
			}

			// Aplicamos los estilos definidos anteriormente
			rowHeadInspeccion.getCell(0).setCellStyle(headerStyle);
			rowHeadInspeccion.getCell(1).setCellStyle(headerStyle);
			rowHeadInspeccion.getCell(2).setCellStyle(headerStyle);
			rowInspeccion.getCell(0).setCellStyle(inspeccionStyle);
			rowInspeccion.getCell(1).setCellStyle(inspeccionStyle);
			rowInspeccion.getCell(2).setCellStyle(inspeccionStyle);
			rowHeadInspeccion.setHeightInPoints(20);
			rowInspeccion.setHeightInPoints(20);

			// Creamos el resto de filas con sus celdas
			for (PreguntasRespuestasProtocolo preguntaRespuesta : preguntasRespuestasProtocolo) {
				HSSFRow preguntaProtocoloRow = sheet.createRow(++rowCount);

				if (castellano) {
					preguntaProtocoloRow.createCell(0)
							.setCellValue(preguntaRespuesta.getPreguntasProtocolo().getDescripcionCastellano());
				} else if (euskera) {
					preguntaProtocoloRow.createCell(0)
							.setCellValue(preguntaRespuesta.getPreguntasProtocolo().getDescripcionEuskera());
				}

				switch (preguntaRespuesta.getPreguntasProtocolo().getIdTipoPregunta()) {
				case Constantes.TIPO_PREGUNTA_NUMERICO:
					preguntaProtocoloRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTencico.numero", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_FECHA:
					preguntaProtocoloRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.fecha", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_TEXTO_LIBRE:
					preguntaProtocoloRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.texto", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_CORRECTO_INCORRECTO:
					preguntaProtocoloRow.createCell(1).setCellValue(
							appMessageSource.getMessage("excel.informeTecnico.correctoIncorrecto", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_SINO:
					preguntaProtocoloRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.siNo", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_CHECKBOX:
					preguntaProtocoloRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.checkbox", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_TITULO:
					preguntaProtocoloRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.tipoTitulo", null, locale));
					break;

				default:
					preguntaProtocoloRow.createCell(1).setCellValue("");
					break;

				}

				if (preguntaRespuesta.getRespuestasProtocolo() != null
						&& preguntaRespuesta.getRespuestasProtocolo().getIdRespuestaProtocolo() != null) {

					if (preguntaRespuesta.getPreguntasProtocolo() != null
							&& preguntaRespuesta.getPreguntasProtocolo()
									.getIdTipoPregunta() == Constantes.TIPO_PREGUNTA_CHECKBOX
							&& preguntaRespuesta.getRespuestasProtocolo() != null
							&& preguntaRespuesta.getRespuestasProtocolo().getRespuesta() != null) {

						String respuestaOpciones = "";
						String[] respuestaOpcionesIds = preguntaRespuesta.getRespuestasProtocolo().getRespuesta()
								.split(";");

						// Si la pregunta es de tipo checkbox buscamos las
						// opciones para mostrar las descripciones en lugar de
						// los ids
						for (int i = 0; i < respuestaOpcionesIds.length; i++) {
							OpcionesPrePro opcionABuscar = this.opcionesPreProDao
									.find(new OpcionesPrePro(Integer.parseInt(respuestaOpcionesIds[i])));

							if (castellano) {
								respuestaOpciones += opcionABuscar.getDescripcionCastellano() + "; ";
							} else if (euskera) {
								respuestaOpciones += opcionABuscar.getDescripcionEuskera() + "; ";
							}

						}

						preguntaProtocoloRow.createCell(2).setCellValue(respuestaOpciones);
					} else {
						preguntaProtocoloRow.createCell(2)
								.setCellValue(preguntaRespuesta.getRespuestasProtocolo().getRespuesta());
					}

				} else {
					preguntaProtocoloRow.createCell(2).setCellValue("");
				}

				preguntaProtocoloRow.createCell(3);

				switch (preguntaRespuesta.getPreguntasProtocolo().getIdTipoPregunta()) {
				case Constantes.TIPO_PREGUNTA_CORRECTO_INCORRECTO:
					preguntaProtocoloRow.getCell(3).setCellValue(appMessageSource
							.getMessage("excel.informeTecnico.correctoIncorrectoOpciones", null, locale));
					preguntaProtocoloRow.getCell(3).setCellStyle(preguntaStyle);
					break;

				case Constantes.TIPO_PREGUNTA_SINO:
					preguntaProtocoloRow.getCell(3).setCellValue(
							appMessageSource.getMessage("excel.informeTecnico.siNoOpciones", null, locale));
					preguntaProtocoloRow.getCell(3).setCellStyle(preguntaStyle);
					break;

				default:
					preguntaProtocoloRow.getCell(3).setCellStyle(disabledStyle);
					break;
				}

				if (!opcionesPrePro.isEmpty()) {

					String stringOpciones = "";
					String opcionesIds = "";

					preguntaProtocoloRow.createCell(6);

					for (OpcionesPrePro opcion : opcionesPrePro) {
						if (preguntaRespuesta.getPreguntasProtocolo().getIdPreguntaProtocolo()
								.equals(opcion.getIdPreguntaProtocolo())) {
							opcionesIds += opcion.getIdOpcionPrePro() + ";";
							if (castellano) {
								stringOpciones += opcion.getDescripcionCastellano() + ";";
							} else if (euskera) {
								stringOpciones += opcion.getDescripcionEuskera() + ";";
							}

							preguntaProtocoloRow.getCell(3).setCellStyle(preguntaStyle);
							preguntaProtocoloRow.getCell(3).setCellValue(stringOpciones);
							preguntaProtocoloRow.getCell(6).setCellValue(opcionesIds);
						}
					}
				}

				preguntaProtocoloRow.createCell(4).setCellValue(preguntaRespuesta.getIdRelProPre());
				preguntaProtocoloRow.createCell(5)
						.setCellValue(preguntaRespuesta.getPreguntasProtocolo().getIdTipoPregunta());

				preguntaProtocoloRow.getCell(0).setCellStyle(preguntaStyle);

				if (preguntaRespuesta.getPreguntasProtocolo().getIdTipoPregunta() == Constantes.TIPO_PREGUNTA_TITULO) {
					preguntaProtocoloRow.getCell(1).setCellStyle(preguntaStyle);
					preguntaProtocoloRow.getCell(2).setCellStyle(disabledStyle);
				} else {
					preguntaProtocoloRow.getCell(1).setCellStyle(preguntaStyle);
					preguntaProtocoloRow.getCell(2).setCellStyle(respuestaStyle);
				}

				preguntaProtocoloRow.setHeightInPoints(20);

			}

			// Creamos la fila cabecera de las preguntas de expediente
			if (preguntasRespuestasExpediente.size() > 0) {
				HSSFRow rowHeadPreguntasExpediente = sheet.createRow(++rowCount);
				rowHeadPreguntasExpediente.createCell(0).setCellValue(
						appMessageSource.getMessage("excel.informeTecnico.preguntasExpediente", null, locale));
				rowHeadPreguntasExpediente.createCell(1)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.tipoPreguntas", null, locale));
				rowHeadPreguntasExpediente.createCell(2)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.respuestas", null, locale));
				rowHeadPreguntasExpediente.createCell(3)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.opciones", null, locale));
				rowHeadPreguntasExpediente.getCell(0).setCellStyle(headerStyle);
				rowHeadPreguntasExpediente.getCell(1).setCellStyle(headerStyle);
				rowHeadPreguntasExpediente.getCell(2).setCellStyle(headerStyle);
				rowHeadPreguntasExpediente.getCell(3).setCellStyle(headerStyle);
				rowHeadPreguntasExpediente.setHeightInPoints(20);
			}

			// Creamos las filas con las preguntas del expediente
			for (PreguntasRespuestasExpediente preguntaRespuestaExpediente : preguntasRespuestasExpediente) {
				HSSFRow preguntaExpedienteRow = sheet.createRow(++rowCount);

				if (castellano) {
					preguntaExpedienteRow.createCell(0).setCellValue(
							preguntaRespuestaExpediente.getPreguntasExpediente().getDescripcionCastellano());
				} else if (euskera) {
					preguntaExpedienteRow.createCell(0)
							.setCellValue(preguntaRespuestaExpediente.getPreguntasExpediente().getDescripcionEuskera());
				}

				switch (preguntaRespuestaExpediente.getPreguntasExpediente().getIdTipoPregunta()) {
				case Constantes.TIPO_PREGUNTA_NUMERICO:
					preguntaExpedienteRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTencico.numero", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_FECHA:
					preguntaExpedienteRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.fecha", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_TEXTO_LIBRE:
					preguntaExpedienteRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.texto", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_CORRECTO_INCORRECTO:
					preguntaExpedienteRow.createCell(1).setCellValue(
							appMessageSource.getMessage("excel.informeTecnico.correctoIncorrecto", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_SINO:
					preguntaExpedienteRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.siNo", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_CHECKBOX:
					preguntaExpedienteRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.checkbox", null, locale));
					break;

				case Constantes.TIPO_PREGUNTA_TITULO:
					preguntaExpedienteRow.createCell(1)
							.setCellValue(appMessageSource.getMessage("excel.informeTecnico.tipoTitulo", null, locale));
					break;

				default:
					preguntaExpedienteRow.createCell(1).setCellValue("");
					break;

				}

				if (preguntaRespuestaExpediente.getRespuestasExpediente() != null
						&& preguntaRespuestaExpediente.getRespuestasExpediente().getIdRespuestaExpediente() != null) {

					if (preguntaRespuestaExpediente.getPreguntasExpediente() != null
							&& preguntaRespuestaExpediente.getPreguntasExpediente()
									.getIdTipoPregunta() == Constantes.TIPO_PREGUNTA_CHECKBOX
							&& preguntaRespuestaExpediente.getRespuestasExpediente() != null
							&& preguntaRespuestaExpediente.getRespuestasExpediente().getRespuesta() != null) {

						String respuestaOpciones = "";
						String[] respuestaOpcionesIds = preguntaRespuestaExpediente.getRespuestasExpediente()
								.getRespuesta().split(";");

						// Si la pregunta es de tipo checkbox buscamos las
						// opciones para mostrar las descripciones en lugar de
						// los ids
						for (int i = 0; i < respuestaOpcionesIds.length; i++) {
							OpcionesPreExp opcionABuscar = this.opcionesPreExpDao
									.find(new OpcionesPreExp(Integer.parseInt(respuestaOpcionesIds[i])));

							if (castellano) {
								respuestaOpciones += opcionABuscar.getDescripcionCastellano() + "; ";
							} else if (euskera) {
								respuestaOpciones += opcionABuscar.getDescripcionEuskera() + "; ";
							}

						}

						preguntaExpedienteRow.createCell(2).setCellValue(respuestaOpciones);
					} else {
						preguntaExpedienteRow.createCell(2)
								.setCellValue(preguntaRespuestaExpediente.getRespuestasExpediente().getRespuesta());
					}

				} else {
					preguntaExpedienteRow.createCell(2).setCellValue("");
				}

				preguntaExpedienteRow.createCell(3);

				switch (preguntaRespuestaExpediente.getPreguntasExpediente().getIdTipoPregunta()) {
				case Constantes.TIPO_PREGUNTA_CORRECTO_INCORRECTO:
					preguntaExpedienteRow.getCell(3).setCellValue(appMessageSource
							.getMessage("excel.informeTecnico.correctoIncorrectoOpciones", null, locale));
					preguntaExpedienteRow.getCell(3).setCellStyle(preguntaStyle);
					break;

				case Constantes.TIPO_PREGUNTA_SINO:
					preguntaExpedienteRow.getCell(3).setCellValue(
							appMessageSource.getMessage("excel.informeTecnico.siNoOpciones", null, locale));
					preguntaExpedienteRow.getCell(3).setCellStyle(preguntaStyle);
					break;

				default:
					preguntaExpedienteRow.getCell(3).setCellStyle(disabledStyle);
					break;
				}

				if (!opcionesPreExp.isEmpty()) {

					String stringOpciones = "";
					String opcionesIds = "";
					preguntaExpedienteRow.createCell(6);

					for (OpcionesPreExp opcion : opcionesPreExp) {
						if (preguntaRespuestaExpediente.getPreguntasExpediente().getIdPreguntaExpediente()
								.equals(opcion.getIdPreguntaExpediente())) {
							opcionesIds += opcion.getIdOpcionPreExp() + ";";
							if (castellano) {
								stringOpciones += opcion.getDescripcionCastellano() + ";";
							} else if (euskera) {
								stringOpciones += opcion.getDescripcionEuskera() + ";";
							}

							preguntaExpedienteRow.getCell(3).setCellValue(stringOpciones);
							preguntaExpedienteRow.getCell(3).setCellStyle(preguntaStyle);
							preguntaExpedienteRow.getCell(6).setCellValue(opcionesIds);
						}
					}
				}

				preguntaExpedienteRow.createCell(4)
						.setCellValue(preguntaRespuestaExpediente.getPreguntasExpediente().getIdPreguntaExpediente());
				preguntaExpedienteRow.createCell(5)
						.setCellValue(preguntaRespuestaExpediente.getPreguntasExpediente().getIdTipoPregunta());

				preguntaExpedienteRow.getCell(0).setCellStyle(preguntaStyle);

				if (preguntaRespuestaExpediente.getPreguntasExpediente()
						.getIdTipoPregunta() == Constantes.TIPO_PREGUNTA_TITULO) {
					preguntaExpedienteRow.getCell(1).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(2).setCellStyle(disabledStyle);
				} else {
					preguntaExpedienteRow.getCell(1).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(2).setCellStyle(respuestaStyle);
				}

				preguntaExpedienteRow.setHeightInPoints(20);

			}

			// Anchura de las columnas
			sheet.autoSizeColumn(0);
			sheet.autoSizeColumn(1);
			sheet.autoSizeColumn(2);
			if (!opcionesPrePro.isEmpty() || !opcionesPreExp.isEmpty()) {
				sheet.autoSizeColumn(3);
			}

			// Ocultar columnas con los ids de las preguntas
			sheet.setColumnHidden(4, true);
			sheet.setColumnHidden(5, true);
			sheet.setColumnHidden(6, true);

			FileOutputStream fileOut = new FileOutputStream(fileName);
			workbook.write(fileOut);
			fileOut.close();

			PreguntasProtocoloServiceImpl.logger.info("[GET - exportarExcel] : Archivo generado");

			// Creamos el archivo a descargar
			File fileToDownload = new File(fileName);
			InputStream in = new FileInputStream(fileToDownload);

			// Recogemos el MIME type del fichero
			String mimeType = new MimetypesFileTypeMap().getContentType(fileName);

			if (mimeType == null) {
				// Si no se encuentra lo seteamos manualmente
				mimeType = "application/octet-stream";
			}
			PreguntasProtocoloServiceImpl.logger.info("[GET - exportarExcel] : MIME type: " + mimeType);

			// Seteamos el contentType de la response
			response.setContentType(mimeType);
			response.setContentLength((int) fileToDownload.length());

			// Descargamos el archivo
			response.setHeader("Content-Disposition", "attachment; filename=\"" + fileToDownload.getName() + "\"");

			// Obtenemos el outputStream de la response
			OutputStream outStream = response.getOutputStream();

			byte[] buffer = new byte[4096];
			int bytesRead = -1;

			while ((bytesRead = in.read(buffer)) != -1) {
				outStream.write(buffer, 0, bytesRead);
			}

			// Cerramos el InputStream y el OutputStream
			in.close();
			outStream.close();

			PreguntasProtocoloServiceImpl.logger.info("[GET - exportarExcel] : Archivo descargado con éxito");

		} catch (Exception e) {
			PreguntasProtocoloServiceImpl.logger.error(e.getMessage());
		}

	}

	/**
	 * Método que importa las respuestas de una hoja de Excel y las guarda en
	 * BBDD.
	 * 
	 */
	@Override
	public ListaPreguntasRespuestas importarExcel(MultipartFile excelAImportar) throws Exception {

		Locale locale = LocaleContextHolder.getLocale();
		boolean filaValidar = false;
		boolean filaProtocolo = false;
		boolean filaExpediente = false;
		String tituloFila;

		ListaPreguntasRespuestas listaPreguntasRespuestas = new ListaPreguntasRespuestas();
		List<PreguntasRespuestasProtocolo> preguntasRespuestasProtocolo = new ArrayList<PreguntasRespuestasProtocolo>();
		List<PreguntasRespuestasExpediente> preguntasRespuestasValidar = new ArrayList<PreguntasRespuestasExpediente>();
		List<PreguntasRespuestasExpediente> preguntasRespuestasExpediente = new ArrayList<PreguntasRespuestasExpediente>();

		// Creamos un Workbook de un archivo Excel (.xls or .xlsx)
		HSSFWorkbook workbook = new HSSFWorkbook(excelAImportar.getInputStream());

		// Cogemos la primera hoja (en este caso solo existe una hoja)
		HSSFSheet sheet = workbook.getSheetAt(0);

		// Creamos un DataFormatter para recoger los valores de las celdas como
		// String
		DataFormatter dataFormatter = new DataFormatter();

		// Iteramos sobre las filas de la hoja
		for (Row respuestaRow : sheet) {

			tituloFila = dataFormatter.formatCellValue(respuestaRow.getCell(0));

			// Si es la cabecera de preguntas a validar nos saltamos esa fila y
			// marcamos que las siguientes filas serán las preguntas a validar
			// (filaValidar = true)
			if (tituloFila.indexOf(
					appMessageSource.getMessage("excel.informeTecnico.preguntasValidar", null, locale)) != -1) {
				filaValidar = true;
				filaProtocolo = false;
				filaExpediente = false;
				continue;

				// Si es la cabecera de las preguntas del protocolo nos saltamos
				// esa fila y marcamos que las siguientes filas serán las
				// preguntas del protocolo (filaProtocolo = true)
			} else if (tituloFila.indexOf(
					appMessageSource.getMessage("excel.informeTecnico.preguntasProtocolo", null, locale)) != -1) {
				filaValidar = false;
				filaProtocolo = true;
				filaExpediente = false;
				continue;

				// Si es la cabecera de las preguntas del expediente nos
				// saltamos esa fila y marcamos que las siguientes filas serán
				// las preguntas del expediente ( filaExpediente = true)
			} else if (tituloFila.indexOf(
					appMessageSource.getMessage("excel.informeTecnico.preguntasExpediente", null, locale)) != -1) {
				filaValidar = false;
				filaProtocolo = false;
				filaExpediente = true;
				continue;
			}

			// Si es la primera o segunda fila (datos de la inspección) o no es
			// una pregunta, nos saltamos esa fila
			if (sheet.getRow(0) == respuestaRow || sheet.getRow(1) == respuestaRow
					|| "".equals(dataFormatter.formatCellValue(respuestaRow.getCell(4)))) {
				continue;
			}

			if (filaValidar && Constantes.TIPO_PREGUNTA_TITULO != Integer
					.parseInt(dataFormatter.formatCellValue(respuestaRow.getCell(6)))) {
				PreguntasExpediente preguntaValidar = new PreguntasExpediente();
				RespuestasExpediente respuestaValidar = new RespuestasExpediente();
				PreguntasRespuestasExpediente preguntaRespuestaValidar = new PreguntasRespuestasExpediente();

				// Recogemos los valores que necesitamos
				String verificadoCell = dataFormatter.formatCellValue(respuestaRow.getCell(2));
				String idPreguntaExpedienteCell = dataFormatter.formatCellValue(respuestaRow.getCell(4));
				String idTipoPreguntaExpCell = dataFormatter.formatCellValue(respuestaRow.getCell(6));

				// Si la pregunta es de tipo fecha la formateamos dependiendo
				// del idioma en el que esté la aplicación
				if (Integer.parseInt(idTipoPreguntaExpCell) == Constantes.TIPO_PREGUNTA_FECHA) {
					SimpleDateFormat formatoFecha = new SimpleDateFormat();
					if (locale.toString().equals(Constantes.CASTELLANO)) {
						formatoFecha = new SimpleDateFormat(Constantes.FORMATO_FECHA_ES);
					} else if (locale.toString().equals(Constantes.EUSKERA)) {
						formatoFecha = new SimpleDateFormat(Constantes.FORMATO_FECHA_EU);
					}

					try {
						Date fecha = respuestaRow.getCell(2).getDateCellValue();
						verificadoCell = formatoFecha.format(fecha);
					} catch (Exception e) {
						PreguntasProtocoloServiceImpl.logger.error(e.getMessage());
						verificadoCell = dataFormatter.formatCellValue(respuestaRow.getCell(2));
					}
				}

				PreguntasExpediente preguntaExpediente = new PreguntasExpediente();
				preguntaExpediente.setIdPreguntaExpediente(Integer.parseInt(idPreguntaExpedienteCell));
				respuestaValidar.setPreguntaExpediente(preguntaExpediente);
				preguntaValidar.setIdTipoPregunta(Integer.parseInt(idTipoPreguntaExpCell));
				respuestaValidar.setRespuesta(verificadoCell);
				preguntaRespuestaValidar.setPreguntasExpediente(preguntaValidar);
				preguntaRespuestaValidar.setRespuestasExpediente(respuestaValidar);

				preguntaRespuestaValidar = this.respuestasExpedienteService
						.parseRespuestasExcelValidar(preguntaRespuestaValidar);
				if (preguntaRespuestaValidar == null) {
					PreguntasRespuestasExpediente preguntaRespuestaErrorValidar = new PreguntasRespuestasExpediente();
					preguntaRespuestaErrorValidar.setExcelErrorRow(respuestaRow.getRowNum() + 1);
					preguntasRespuestasValidar.add(preguntaRespuestaErrorValidar);
				} else {
					preguntasRespuestasValidar.add(preguntaRespuestaValidar);
				}

			}

			if (filaProtocolo && Constantes.TIPO_PREGUNTA_TITULO != Integer
					.parseInt(dataFormatter.formatCellValue(respuestaRow.getCell(5)))) {

				PreguntasProtocolo preguntaProtocolo = new PreguntasProtocolo();
				RespuestasProtocolo respuestaProtocolo = new RespuestasProtocolo();
				PreguntasRespuestasProtocolo preguntaRespuestaProtocolo = new PreguntasRespuestasProtocolo();

				// Recogemos los valores que necesitamos
				String respuestaCell = dataFormatter.formatCellValue(respuestaRow.getCell(2));
				String idRelProPreCell = dataFormatter.formatCellValue(respuestaRow.getCell(4));
				String idTipoPreguntaCell = dataFormatter.formatCellValue(respuestaRow.getCell(5));

				// Si la pregunta es de tipo fecha la formateamos dependiendo
				// del idioma en el que esté la aplicación
				if (Integer.parseInt(idTipoPreguntaCell) == Constantes.TIPO_PREGUNTA_FECHA) {
					SimpleDateFormat formatoFecha = new SimpleDateFormat();
					if (locale.toString().equals(Constantes.CASTELLANO)) {
						formatoFecha = new SimpleDateFormat(Constantes.FORMATO_FECHA_ES);
					} else if (locale.toString().equals(Constantes.EUSKERA)) {
						formatoFecha = new SimpleDateFormat(Constantes.FORMATO_FECHA_EU);
					}

					try {
						Date fecha = respuestaRow.getCell(2).getDateCellValue();
						respuestaCell = formatoFecha.format(fecha);
					} catch (Exception e) {
						PreguntasProtocoloServiceImpl.logger.error(e.getMessage());
						respuestaCell = dataFormatter.formatCellValue(respuestaRow.getCell(2));
					}
				}

				if (Integer.parseInt(idTipoPreguntaCell) == Constantes.TIPO_PREGUNTA_CHECKBOX
						&& !"".equals(dataFormatter.formatCellValue(respuestaRow.getCell(6)))) {
					String opcionesIds = dataFormatter.formatCellValue(respuestaRow.getCell(6));
					String opcionesDesc = dataFormatter.formatCellValue(respuestaRow.getCell(3));
					String[] descOpcion = opcionesDesc.split(";");
					String[] idOpcion = opcionesIds.split(";");

					List<OpcionesPrePro> opciones = new ArrayList<OpcionesPrePro>();

					for (int i = 0; i < idOpcion.length; i++) {
						OpcionesPrePro opcion = new OpcionesPrePro();
						opcion.setIdOpcionPrePro(Integer.parseInt(idOpcion[i]));
						opcion.setDescripcionCastellano(descOpcion[i]);
						opciones.add(opcion);
					}

					preguntaProtocolo.setOpcionesPrePro(opciones);

				}

				preguntaProtocolo.setIdTipoPregunta(Integer.parseInt(idTipoPreguntaCell));
				respuestaProtocolo.setRespuesta(respuestaCell);
				preguntaRespuestaProtocolo.setPreguntasProtocolo(preguntaProtocolo);
				preguntaRespuestaProtocolo.setRespuestasProtocolo(respuestaProtocolo);
				preguntaRespuestaProtocolo.setIdRelProPre(Integer.parseInt(idRelProPreCell));
				respuestaProtocolo.setIdRelProPre(Integer.parseInt(idRelProPreCell));

				preguntaRespuestaProtocolo = this.respuestasProtocoloService
						.parseRespuestasExcelProtocolo(preguntaRespuestaProtocolo);
				if (preguntaRespuestaProtocolo == null) {
					PreguntasRespuestasProtocolo preguntaRespuestaErrorPro = new PreguntasRespuestasProtocolo();
					preguntaRespuestaErrorPro.setExcelErrorRow(respuestaRow.getRowNum() + 1);
					preguntasRespuestasProtocolo.add(preguntaRespuestaErrorPro);
				} else {
					preguntasRespuestasProtocolo.add(preguntaRespuestaProtocolo);
				}

			}

			if (filaExpediente && Constantes.TIPO_PREGUNTA_TITULO != Integer
					.parseInt(dataFormatter.formatCellValue(respuestaRow.getCell(5)))) {
				PreguntasExpediente preguntaExpediente = new PreguntasExpediente();
				RespuestasExpediente respuestaExpediente = new RespuestasExpediente();
				PreguntasRespuestasExpediente preguntaRespuestaExpediente = new PreguntasRespuestasExpediente();

				// Recogemos los valores que necesitamos
				String respuestaCell = dataFormatter.formatCellValue(respuestaRow.getCell(2));
				String idPreguntaExpedienteCell = dataFormatter.formatCellValue(respuestaRow.getCell(4));
				String idTipoPreguntaCell = dataFormatter.formatCellValue(respuestaRow.getCell(5));

				// Si la pregunta es de tipo fecha la formateamos dependiendo
				// del idioma en el que esté la aplicación
				if (Integer.parseInt(idTipoPreguntaCell) == Constantes.TIPO_PREGUNTA_FECHA) {
					SimpleDateFormat formatoFecha = new SimpleDateFormat();
					if (locale.toString().equals(Constantes.CASTELLANO)) {
						formatoFecha = new SimpleDateFormat(Constantes.FORMATO_FECHA_ES);
					} else if (locale.toString().equals(Constantes.EUSKERA)) {
						formatoFecha = new SimpleDateFormat(Constantes.FORMATO_FECHA_EU);
					}

					try {
						Date fecha = respuestaRow.getCell(2).getDateCellValue();
						respuestaCell = formatoFecha.format(fecha);
					} catch (Exception e) {
						PreguntasProtocoloServiceImpl.logger.error(e.getMessage());
						respuestaCell = dataFormatter.formatCellValue(respuestaRow.getCell(2));
					}
				}

				if (Integer.parseInt(idTipoPreguntaCell) == Constantes.TIPO_PREGUNTA_CHECKBOX
						&& !"".equals(dataFormatter.formatCellValue(respuestaRow.getCell(6)))) {
					String opcionesIds = dataFormatter.formatCellValue(respuestaRow.getCell(6));
					String opcionesDesc = dataFormatter.formatCellValue(respuestaRow.getCell(3));
					String[] descOpcion = opcionesDesc.split(";");
					String[] idOpcion = opcionesIds.split(";");

					List<OpcionesPreExp> opciones = new ArrayList<OpcionesPreExp>();

					for (int i = 0; i < idOpcion.length; i++) {
						OpcionesPreExp opcion = new OpcionesPreExp();
						opcion.setIdOpcionPreExp(Integer.parseInt(idOpcion[i]));
						opcion.setDescripcionCastellano(descOpcion[i]);
						opciones.add(opcion);
					}

					preguntaExpediente.setOpcionesPreExp(opciones);

				}

				preguntaExpediente.setIdPreguntaExpediente(Integer.parseInt(idPreguntaExpedienteCell));
				respuestaExpediente.setPreguntaExpediente(preguntaExpediente);
				preguntaExpediente.setIdTipoPregunta(Integer.parseInt(idTipoPreguntaCell));
				respuestaExpediente.setRespuesta(respuestaCell);
				preguntaRespuestaExpediente.setPreguntasExpediente(preguntaExpediente);
				preguntaRespuestaExpediente.setRespuestasExpediente(respuestaExpediente);

				preguntaRespuestaExpediente = this.respuestasExpedienteService
						.parseRespuestasExcelExpediente(preguntaRespuestaExpediente);
				if (preguntaRespuestaExpediente == null) {
					PreguntasRespuestasExpediente preguntaRespuestaErrorExpediente = new PreguntasRespuestasExpediente();
					preguntaRespuestaErrorExpediente.setExcelErrorRow(respuestaRow.getRowNum() + 1);
					preguntasRespuestasExpediente.add(preguntaRespuestaErrorExpediente);
				} else {
					preguntasRespuestasExpediente.add(preguntaRespuestaExpediente);
				}

			}

		}

		listaPreguntasRespuestas.setPreguntasRespuestasProtocolo(preguntasRespuestasProtocolo);
		listaPreguntasRespuestas.setPreguntasRespuestasValidar(preguntasRespuestasValidar);
		listaPreguntasRespuestas.setPreguntasRespuestasExpediente(preguntasRespuestasExpediente);

		return listaPreguntasRespuestas;

	}

	@Override
	public boolean findPreguntasEnOtroProtocolo(Integer idProtocolo, Integer idPreguntaProtocolo) {
		return this.preguntasProtocoloDao.findPreguntasEnOtroProtocolo(idProtocolo, idPreguntaProtocolo);
	}

	@Override
	public void borrarPreguntaRelProPre(RelProPre relProPre) {
		this.preguntasProtocoloDao.borrarPreguntaRelProPre(relProPre);
	}

	@Override
	public void borrarRelProPreByPregunta(RelProPre relProPre) {
		this.preguntasProtocoloDao.borrarRelProPreByPregunta(relProPre);
	}

	@Override
	public void borrarRelProPreByProtocolo(Protocolos protocolos) {
		this.preguntasProtocoloDao.borrarRelProPreByProtocolo(protocolos);
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public RelProPre insertRelProPre(RelProPre relProPre) {
		return this.preguntasProtocoloDao.insertRelProPre(relProPre);
	}

	@Override
	public List<PreguntasProtocolo> findByProtocolo(PreguntasProtocolo filterPreguntasProtocolo,
			TableRequestDto tableRequestDto, boolean startsWith) {
		return this.preguntasProtocoloDao.findByProtocolo(filterPreguntasProtocolo, tableRequestDto, startsWith);
	}

	@Override
	public RelProPre updateRelProPre(RelProPre relProPre) {
		return this.preguntasProtocoloDao.updateRelProPre(relProPre);
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public List<PreguntasProtocolo> getPreguntasRelProPre(PreguntasProtocolo preguntaProtocolo, Integer validar) {
		return this.preguntasProtocoloDao.getPreguntasRelProPre(preguntaProtocolo, validar);
	}

	@Override
	public boolean findValidarEnOtroProtocolo(PreguntasProtocolo preguntaValidar) {
		return this.preguntasProtocoloDao.findValidarEnOtroProtocolo(preguntaValidar);

	}

	@Override
	public boolean findIdentDatoEstablecimientoRepetido(PreguntasProtocolo preguntaValidar) {
		return this.preguntasProtocoloDao.findIdentDatoEstablecimientoRepetido(preguntaValidar);
	}

	@Override
	public List<PreguntasProtocolo> findAllREST(PreguntasProtocolo filterPreguntasProtocolo) {
		return this.preguntasProtocoloDao.findAllREST(filterPreguntasProtocolo);
	}

	@Override
	public void getExcelPreguntasValidar(List<PreguntasProtocolo> listaPreguntasValidar, HttpServletResponse response) {

		Locale locale = LocaleContextHolder.getLocale();

		boolean euskera = false;

		// Configuramos variables de idioma.
		if (locale.toString().equals(Constantes.EUSKERA)) {
			euskera = true;
		}

		try {

			// Nombre del archivo
			String fileName = appMessageSource.getMessage("excel.preguntasProtocolo.sheetName", null, locale) + ".xls";

			// Creamos la hoja
			HSSFWorkbook workbook = new HSSFWorkbook();
			HSSFSheet sheet = workbook
					.createSheet(appMessageSource.getMessage("excel.preguntasProtocolo.sheetName", null, locale));

			// Definimos los estilos y fuentes de la hoja
			HSSFFont font = workbook.createFont();
			font.setFontName(HSSFFont.FONT_ARIAL);
			font.setFontHeightInPoints((short) 12);
			font.setBoldweight(Font.BOLDWEIGHT_BOLD);

			HSSFCellStyle headerStyle = workbook.createCellStyle();
			headerStyle.setBorderBottom(CellStyle.BORDER_MEDIUM);
			headerStyle.setFont(font);
			headerStyle.setAlignment(CellStyle.ALIGN_CENTER);

			HSSFCellStyle disabledStyle = workbook.createCellStyle();
			disabledStyle.setFillPattern(CellStyle.THIN_FORWARD_DIAG);

			// Creamos la fila cabecera
			HSSFRow rowHead = sheet.createRow(0);

			rowHead.createCell(0)
					.setCellValue(appMessageSource.getMessage("excel.preguntasProtocolo.tipoPregunta", null, locale));
			rowHead.createCell(1)
					.setCellValue(appMessageSource.getMessage("excel.preguntasProtocolo.pregunta", null, locale));
			rowHead.createCell(2).setCellValue(
					appMessageSource.getMessage("excel.preguntasProtocolo.datoEstablecimiento", null, locale));

			rowHead.getCell(0).setCellStyle(headerStyle);
			rowHead.getCell(1).setCellStyle(headerStyle);
			rowHead.getCell(2).setCellStyle(headerStyle);

			// Creamos el resto de filas con sus celdas
			int rowCount = 1;
			for (PreguntasProtocolo preguntasProtocolo : listaPreguntasValidar) {

				HSSFRow preguntasProtocoloRow = sheet.createRow(rowCount++);

				preguntasProtocoloRow.createCell(0)
						.setCellValue((euskera) ? preguntasProtocolo.getTipoPregunta().getDescripcionEuskera()
								: preguntasProtocolo.getTipoPregunta().getDescripcionCastellano());
				preguntasProtocoloRow.createCell(1).setCellValue((euskera) ? preguntasProtocolo.getDescripcionEuskera()
						: preguntasProtocolo.getDescripcionCastellano());
				preguntasProtocoloRow.createCell(2).setCellValue(preguntasProtocolo.getIdentDatoEstablecimiento());
			}

			// Anchura de las columnas
			sheet.autoSizeColumn(0);
			sheet.autoSizeColumn(1);
			sheet.autoSizeColumn(2);

			FileOutputStream fileOut = new FileOutputStream(fileName);
			workbook.write(fileOut);
			fileOut.close();

			PreguntasProtocoloServiceImpl.logger.info("[GET - exportarExcel] : Archivo generado");

			// Creamos el archivo a descargar
			File fileToDownload = new File(fileName);
			InputStream in = new FileInputStream(fileToDownload);

			// Recogemos el MIME type del fichero
			String mimeType = new MimetypesFileTypeMap().getContentType(fileName);

			if (mimeType == null) {
				// Si no se encuentra lo seteamos manualmente
				mimeType = "application/octet-stream";
			}
			PreguntasProtocoloServiceImpl.logger.info("[GET - exportarExcel] : MIME type: " + mimeType);

			// Seteamos el contentType de la response
			response.setContentType(mimeType);
			response.setContentLength((int) fileToDownload.length());

			// Descargamos el archivo
			response.setHeader("Content-Disposition", "attachment; filename=\"" + fileToDownload.getName() + "\"");

			// Obtenemos el outputStream de la response
			OutputStream outStream = response.getOutputStream();

			byte[] buffer = new byte[4096];
			int bytesRead = -1;

			while ((bytesRead = in.read(buffer)) != -1) {
				outStream.write(buffer, 0, bytesRead);
			}

			// Cerramos el InputStream y el OutputStream
			in.close();
			outStream.close();

			PreguntasProtocoloServiceImpl.logger.info("[GET - exportarExcel] : Archivo descargado con ï¿½xito");

		} catch (Exception e) {
			PreguntasProtocoloServiceImpl.logger.error(e.getMessage());
		}
	}

}
