package com.ejie.ab79.service.preguntasRespuestas;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Formatter;
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.hssf.util.HSSFColor;
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.clientesWS.ab63WebService.DatosValidarWS;
import com.ejie.ab79.comun.Constantes;
import com.ejie.ab79.dao.preguntasRespuestas.FicherosAdjExpDao;
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.REST.servicioWeb.PreguntaRespuestaExpediente;
import com.ejie.ab79.model.REST.servicioWeb.PreguntaRespuestaRelConFac;
import com.ejie.ab79.model.REST.servicioWeb.PreguntaRespuestaValidacion;
import com.ejie.ab79.model.inspecciones.Inspecciones;
import com.ejie.ab79.model.preguntasRespuestas.FicherosAdjExp;
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.RespuestasExpediente;
import com.ejie.ab79.model.preguntasRespuestas.RespuestasProtocolo;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * PreguntasExpedienteServiceImpl  
 * 
 *  
 */

@SuppressWarnings("deprecation")
@Service(value = "preguntasExpedienteService")
public class PreguntasExpedienteServiceImpl implements PreguntasExpedienteService {

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

	@Autowired
	private PreguntasExpedienteDao preguntasExpedienteDao;
	@Autowired
	private OpcionesPreExpDao opcionesPreExpDao;
	@Autowired
	private RespuestasExpedienteService respuestasExpedienteService;
	@Autowired
	private FicherosAdjExpDao ficherosAdjExpDao;
	@Autowired
	private PreguntasProtocoloDao preguntasProtocoloDao;
	@Autowired
	private OpcionesPreProDao opcionesPreProDao;
	@Autowired
	private RespuestasProtocoloService respuestasProtocoloService;

	@Resource
	private ReloadableResourceBundleMessageSource appMessageSource;

	/**
	 * Inserts a single row in the PreguntasExpediente table.
	 *
	 * @param preguntasExpediente
	 *            PreguntasExpediente
	 * @return PreguntasExpediente
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public PreguntasExpediente add(PreguntasExpediente preguntasExpediente) {
		return this.preguntasExpedienteDao.add(preguntasExpediente);
	}

	/**
	 * Updates a single row in the PreguntasExpediente table.
	 *
	 * @param preguntasExpediente
	 *            PreguntasExpediente
	 * @return PreguntasExpediente
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public PreguntasExpediente update(PreguntasExpediente preguntasExpediente) {
		return this.preguntasExpedienteDao.update(preguntasExpediente);
	}

	@Override
	public PreguntasExpediente updatePregunta(PreguntasExpediente preguntaExpediente) {
		return this.preguntasExpedienteDao.updatePregunta(preguntaExpediente);
	}

	/**
	 * Finds a single row in the PreguntasExpediente table.
	 *
	 * @param preguntasExpediente
	 *            PreguntasExpediente
	 * @return PreguntasExpediente
	 */
	@Override
	public PreguntasExpediente find(PreguntasExpediente preguntasExpediente) {
		return this.preguntasExpedienteDao.find(preguntasExpediente);
	}

	@Override
	public PreguntasExpediente findByIdPreguntaMovil(PreguntasExpediente preguntaExpediente) {
		return this.preguntasExpedienteDao.findByIdPreguntaMovil(preguntaExpediente);
	}

	@Override
	public List<PreguntasExpediente> findByInspeccion(Inspecciones inspeccion) {
		return this.preguntasExpedienteDao.findByInspeccion(inspeccion);
	}

	@Override
	public List<PreguntasRespuestasExpediente> findPreguntasRespuestasValidar(Inspecciones inspeccion) {
		return this.preguntasExpedienteDao.findPreguntasRespuestasValidar(inspeccion);
	}

	/**
	 * Deletes a single row in the PreguntasExpediente table.
	 *
	 * @param preguntasExpediente
	 *            PreguntasExpediente
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void remove(PreguntasExpediente preguntasExpediente) {
		this.preguntasExpedienteDao.remove(preguntasExpediente);
	}

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

	@Override
	public List<PreguntasRespuestasExpediente> findPreguntasRespuestasExpediente(Inspecciones inspeccion) {

		List<PreguntasRespuestasExpediente> preguntasRespuestasExpediente = this.preguntasExpedienteDao
				.findPreguntasRespuestasExpediente(inspeccion);
		List<OpcionesPreExp> opcionesPreExp = this.preguntasExpedienteDao.findOpcionesPreExp();
		List<FicherosAdjExp> ficherosAdjExp = this.ficherosAdjExpDao.findFicheros();

		for (PreguntasRespuestasExpediente preguntaRespuesta : preguntasRespuestasExpediente) {
			preguntaRespuesta.getPreguntasExpediente().setOpcionesPreExp(opcionesPreExp);
			preguntaRespuesta.getRespuestasExpediente().setFicherosAdjExp(ficherosAdjExp);
		}

		return preguntasRespuestasExpediente;
	}

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

	@Override
	public List<PreguntaRespuestaExpediente> findPreguntasRespuestasExpedienteREST(Integer idInspeccion) {
		return this.preguntasExpedienteDao.findPreguntasRespuestasExpedienteREST(idInspeccion);
	}

	@Override
	public List<PreguntaRespuestaValidacion> findPreguntasRespuestasValidacionREST(Integer idInspeccion) {
		return this.preguntasExpedienteDao.findPreguntasRespuestasValidacionREST(idInspeccion);
	}

	@Override
	public List<PreguntaRespuestaRelConFac> findPreguntasRespuestasRelConFacREST(Integer idInspeccion) {
		return this.preguntasExpedienteDao.findPreguntasRespuestasRelConFacREST(idInspeccion);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the PreguntasExpediente table.
	 *
	 * @param filterPreguntasExpediente
	 *            PreguntasExpediente
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 */
	@Override
	public void removeMultiple(PreguntasExpediente filterPreguntasExpediente, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		this.preguntasExpedienteDao.removeMultiple(filterPreguntasExpediente, tableRequestDto, startsWith);
	}

	/**
	 * Filter method in the PreguntasExpediente table.
	 *
	 * @param filterPreguntasExpediente
	 *            PreguntasExpediente
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return TableResponseDto<PreguntasExpediente>
	 */
	@Override
	public TableResponseDto<PreguntasExpediente> filter(PreguntasExpediente filterPreguntasExpediente,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<PreguntasExpediente> listaPreguntasExpediente = this.preguntasExpedienteDao
				.findAllLike(filterPreguntasExpediente, tableRequestDto, false);
		Long recordNum = this.preguntasExpedienteDao.findAllLikeCount(
				filterPreguntasExpediente != null ? filterPreguntasExpediente : new PreguntasExpediente(), false);

		TableResponseDto<PreguntasExpediente> usuarioDto = new TableResponseDto<PreguntasExpediente>(tableRequestDto,
				recordNum, listaPreguntasExpediente);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<PreguntasExpediente>> reorderSelection = this.preguntasExpedienteDao
					.reorderSelection(filterPreguntasExpediente, 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<PreguntasExpediente>> reorderSeeker = this.preguntasExpedienteDao
					.reorderSelection(filterPreguntasExpediente, tableRequestDto, startsWith);
			usuarioDto.setReorderedSeeker(reorderSeeker);
			usuarioDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return usuarioDto;
	}

	@Override
	public TableResponseDto<PreguntasExpediente> filterInformeTabla(PreguntasExpediente filterPreguntasExpediente,
			TableRequestDto tableRequestDto, boolean startsWith) {

		List<PreguntasExpediente> listaPreguntasExpediente = this.preguntasExpedienteDao
				.findAllLikeInformeTabla(filterPreguntasExpediente, tableRequestDto, false);

		parseRecogidaResultadoTabla(listaPreguntasExpediente);

		List<FicherosAdjExp> ficherosAdjExp = this.ficherosAdjExpDao.findFicheros();

		for (PreguntasExpediente preguntaExpediente : listaPreguntasExpediente) {
			preguntaExpediente.setFicherosAdjExp(ficherosAdjExp);
		}

		Long recordNum = this.preguntasExpedienteDao.findAllLikeCountInformeTabla(
				filterPreguntasExpediente != null ? filterPreguntasExpediente : new PreguntasExpediente(), false);

		TableResponseDto<PreguntasExpediente> usuarioDto = new TableResponseDto<PreguntasExpediente>(tableRequestDto,
				recordNum, listaPreguntasExpediente);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<PreguntasExpediente>> reorderSelection = this.preguntasExpedienteDao
					.reorderSelectionInformeTabla(filterPreguntasExpediente, 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<PreguntasExpediente>> reorderSeeker = this.preguntasExpedienteDao
					.reorderSelectionInformeTabla(filterPreguntasExpediente, tableRequestDto, startsWith);
			usuarioDto.setReorderedSeeker(reorderSeeker);
			usuarioDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return usuarioDto;
	}

	/**
	 * Searches rows in the PreguntasExpediente table.
	 *
	 * @param filterPreguntasExpediente
	 *            PreguntasExpediente
	 * @param searchPreguntasExpediente
	 *            PreguntasExpediente
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<PreguntasExpediente>>
	 */
	@Override
	public List<TableRowDto<PreguntasExpediente>> search(PreguntasExpediente filterPreguntasExpediente,
			PreguntasExpediente searchPreguntasExpediente, TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.preguntasExpedienteDao.search(filterPreguntasExpediente, searchPreguntasExpediente, tableRequestDto,
				startsWith);
	}

	/**
	 * Reorder the selection made in PreguntasExpediente table.
	 *
	 * @param filterPreguntasExpediente
	 *            PreguntasExpediente
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return Object
	 */
	@Override
	public Object reorderSelection(PreguntasExpediente filterPreguntasExpediente, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.preguntasExpedienteDao.reorderSelection(filterPreguntasExpediente, tableRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */

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

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

	/**
	 * Exporta Datos al clipBoard
	 *
	 */
	@Override
	public List<PreguntasExpediente> getMultiple(PreguntasExpediente filterPreguntasExpediente,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.preguntasExpedienteDao.getMultiple(filterPreguntasExpediente, tableRequestDto, startsWith);
	}

	@Override
	public List<DatosValidarWS> findDatosValidarWS(Inspecciones inspeccion, String idObjetosValidarWS) {
		return this.preguntasExpedienteDao.findDatosValidarWS(inspeccion, idObjetosValidarWS);
	}

	@Override
	public List<String> findIdsObjValidarWS(Inspecciones inspeccion) {
		return this.preguntasExpedienteDao.findIdsObjValidarWS(inspeccion);
	}

	@Override
	public void parseRecogidaResultadoTabla(List<PreguntasExpediente> preguntasExpediente) {

		for (PreguntasExpediente pregunta : preguntasExpediente) {
			if (pregunta.getResultado() != null) {

				switch (pregunta.getIdTipoPregunta()) {
				case Constantes.TIPO_PREGUNTA_CORRECTO_INCORRECTO:
					if (Constantes.CORRECTO_CASTELLANO.equals(pregunta.getResultado())
							|| Constantes.CORRECTO_EUSKERA.equals(pregunta.getResultado())) {
						pregunta.setResultado(Constantes.CORRECTO_NUMERO);
					} else if (Constantes.INCORRECTO_CASTELLANO.equals(pregunta.getResultado())
							|| Constantes.INCORRECTO_EUSKERA.equals(pregunta.getResultado())) {
						pregunta.setResultado(Constantes.INCORRECTO_NUMERO);
					} else if (Constantes.NA.equals(pregunta.getResultado())) {
						pregunta.setResultado(Constantes.NA_NUMERO);
					} else if (pregunta.getResultado() == null) {
						pregunta.setResultado(Constantes.NO_SELECCIONADO);
					}
					break;

				default:
					break;
				}
			}

			if (pregunta.getImporte() != null) {
				StringBuilder sb = new StringBuilder();
				Formatter formatter = new Formatter(sb);
				formatter.format("%(,.2f", pregunta.getImporte());
				formatter.close();

				pregunta.setImporteString(sb.toString());

			}

			if (pregunta.getImporteAdmitido() != null) {
				StringBuilder sb = new StringBuilder();
				Formatter formatter = new Formatter(sb);
				formatter.format("%(,.2f", pregunta.getImporteAdmitido());
				formatter.close();
				pregunta.setImporteAdmitidoString(sb.toString());
			}

		}
	}

	@Override
	public List<PreguntasRespuestasExpediente> parseRecogidaValorValidar(
			List<PreguntasRespuestasExpediente> preguntasRespuestasValidar) {

		for (PreguntasRespuestasExpediente preguntaRespuesta : preguntasRespuestasValidar) {
			if (preguntaRespuesta.getPreguntasExpediente().getValorValidar() != null) {

				switch (preguntaRespuesta.getPreguntasExpediente().getIdTipoPregunta()) {
				case Constantes.TIPO_PREGUNTA_SINO:
					if (Constantes.SINO_SI_CASTELLANO
							.equals(preguntaRespuesta.getPreguntasExpediente().getValorValidar())
							|| Constantes.SINO_SI_EUSKERA
									.equals(preguntaRespuesta.getPreguntasExpediente().getValorValidar())) {
						preguntaRespuesta.getPreguntasExpediente().setValorValidar(Constantes.SINO_SI_NUMERO);
					} else if (Constantes.SINO_NO_CASTELLANO
							.equals(preguntaRespuesta.getPreguntasExpediente().getValorValidar())
							|| Constantes.SINO_NO_EUSKERA
									.equals(preguntaRespuesta.getPreguntasExpediente().getValorValidar())) {
						preguntaRespuesta.getPreguntasExpediente().setValorValidar(Constantes.SINO_NO_NUMERO);
					} else if (Constantes.SINO_NP
							.equals(preguntaRespuesta.getPreguntasExpediente().getValorValidar())) {
						preguntaRespuesta.getPreguntasExpediente().setValorValidar(Constantes.SINO_NP_NUMERO);
					}
					break;

				default:
					break;
				}

			}
		}

		return null;
	}

	@Override
	public void getExcelInformeTabla(List<PreguntasExpediente> preguntasExpedienteTabla,
			List<PreguntasRespuestasProtocolo> preguntasRespuestasProtocolo,
			List<PreguntasRespuestasExpediente> preguntasRespuestasExpediente, HttpServletResponse response,
			boolean concepto, String identificadorInspeccion, String folderNumber, String titulo) {

		List<OpcionesPreExp> opcionesPreExp = this.preguntasExpedienteDao.findOpcionesPreExp();

		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 {

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

			// Creamos la hoja
			HSSFWorkbook workbook = new HSSFWorkbook();
			HSSFSheet sheet = workbook
					.createSheet(appMessageSource.getMessage("excel.informeTecnicoTabla.preguntasTabla", null, locale));
			HSSFSheet sheet2 = workbook
					.createSheet(appMessageSource.getMessage("excel.informeTecnico.preguntasProtocolo", null, locale));
			HSSFSheet sheet3 = workbook.createSheet(
					appMessageSource.getMessage("excel.informeTecnicoTabla.preguntasAcordeon", null, locale));
			sheet.protectSheet(Constantes.PASSWORD_EXCEL);
			sheet2.protectSheet(Constantes.PASSWORD_EXCEL);
			sheet3.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 inspeccionStyle = workbook.createCellStyle();
			inspeccionStyle.setFont(inspeccionFont);
			inspeccionStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

			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.setFillForegroundColor(HSSFColor.GREY_50_PERCENT.index);
			headerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
			headerStyle.setFont(headerFont);

			HSSFCellStyle conceptoStyle = workbook.createCellStyle();
			conceptoStyle.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
			conceptoStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
			conceptoStyle.setFont(headerFont);

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

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

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

			if (concepto) {
				if (preguntasExpedienteTabla.size() > 0) {

					// Creamos la fila cabecera
					HSSFRow rowHead = sheet.createRow(0);
					rowHead.createCell(0).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.concepto", null, locale));
					rowHead.createCell(1).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.importePresentado", null, locale));
					rowHead.createCell(2).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.importeAdmitido", null, locale));
					rowHead.createCell(3).setCellValue(appMessageSource
							.getMessage("excel.informeTecnicoTabla.observacionesTecnico", null, locale));
					rowHead.createCell(4).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.resultado", null, locale));
					rowHead.createCell(5).setCellValue(appMessageSource
							.getMessage("excel.informeTecnicoTabla.observacionesInspeccionCas", null, locale));
					rowHead.createCell(6).setCellValue(appMessageSource
							.getMessage("excel.informeTecnicoTabla.observacionesInspeccionEus", null, locale));
					rowHead.getCell(0).setCellStyle(headerStyle);
					rowHead.getCell(1).setCellStyle(headerStyle);
					rowHead.getCell(2).setCellStyle(headerStyle);
					rowHead.getCell(3).setCellStyle(headerStyle);
					rowHead.getCell(4).setCellStyle(headerStyle);
					rowHead.getCell(5).setCellStyle(headerStyle);
					rowHead.getCell(6).setCellStyle(headerStyle);
					rowHead.setHeightInPoints(20);
				}

				String conceptoAgrupar = "";
				rowCount = 1;

				for (PreguntasExpediente preguntaExpedienteTablaConcepto : preguntasExpedienteTabla) {
					HSSFRow preguntaExpedienteRow = sheet.createRow(rowCount++);
					if (castellano) {
						conceptoAgrupar = preguntaExpedienteTablaConcepto.getDescripcionCastellano();
					} else if (euskera) {
						conceptoAgrupar = preguntaExpedienteTablaConcepto.getDescripcionEuskera();
					}

					preguntaExpedienteRow.createCell(0).setCellValue(conceptoAgrupar);
					preguntaExpedienteRow.getCell(0).setCellStyle(conceptoStyle);
					preguntaExpedienteRow.setHeightInPoints(20);
					sheet.addMergedRegion(new CellRangeAddress(preguntaExpedienteRow.getRowNum(),
							preguntaExpedienteRow.getRowNum(), 0, 6));
					preguntaExpedienteRow = sheet.createRow(rowCount++);

					preguntaExpedienteRow.createCell(0).setCellValue(preguntaExpedienteTablaConcepto.getConcepto());
					preguntaExpedienteRow.createCell(1)
							.setCellValue(preguntaExpedienteTablaConcepto.getImporteString());
					preguntaExpedienteRow.createCell(2)
							.setCellValue(preguntaExpedienteTablaConcepto.getImporteAdmitidoString());
					if (castellano) {
						preguntaExpedienteRow.createCell(3)
								.setCellValue(preguntaExpedienteTablaConcepto.getObservacionesTecnicoCas());
					} else if (euskera) {
						preguntaExpedienteRow.createCell(3)
								.setCellValue(preguntaExpedienteTablaConcepto.getObservacionesTecnicoEus());
					}
					preguntaExpedienteRow.createCell(4).setCellValue(preguntaExpedienteTablaConcepto.getResultado());
					preguntaExpedienteRow.createCell(5)
							.setCellValue(preguntaExpedienteTablaConcepto.getObservacionesInspeccionCas());
					preguntaExpedienteRow.createCell(6)
							.setCellValue(preguntaExpedienteTablaConcepto.getObservacionesInspeccionEus());
					preguntaExpedienteRow.createCell(9)
							.setCellValue(preguntaExpedienteTablaConcepto.getIdPreguntaExpediente());
					preguntaExpedienteRow.createCell(10).setCellValue(Constantes.PREGUNTA_EXPEDIENTE_CON_CONCEPTO);

					preguntaExpedienteRow.getCell(0).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(1).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(2).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(3).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(4).setCellStyle(respuestaStyle);
					preguntaExpedienteRow.getCell(5).setCellStyle(respuestaStyle);
					preguntaExpedienteRow.getCell(6).setCellStyle(respuestaStyle);

					preguntaExpedienteRow.setHeightInPoints(20);

				}
			} else {
				if (preguntasExpedienteTabla.size() > 0) {

					// Creamos la fila cabecera
					HSSFRow rowHead = sheet.createRow(0);
					rowHead.createCell(0).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.fechaFactura", null, locale));
					rowHead.createCell(1).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.numeroFactura", null, locale));
					rowHead.createCell(2).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.proveedor", null, locale));
					rowHead.createCell(3).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.importePresentado", null, locale));
					rowHead.createCell(4).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.importeAdmitido", null, locale));
					rowHead.createCell(5).setCellValue(appMessageSource
							.getMessage("excel.informeTecnicoTabla.observacionesTecnico", null, locale));
					rowHead.createCell(6).setCellValue(
							appMessageSource.getMessage("excel.informeTecnicoTabla.resultado", null, locale));
					rowHead.createCell(7).setCellValue(appMessageSource
							.getMessage("excel.informeTecnicoTabla.observacionesInspeccionCas", null, locale));
					rowHead.createCell(8).setCellValue(appMessageSource
							.getMessage("excel.informeTecnicoTabla.observacionesInspeccionEus", null, locale));
					rowHead.getCell(0).setCellStyle(headerStyle);
					rowHead.getCell(1).setCellStyle(headerStyle);
					rowHead.getCell(2).setCellStyle(headerStyle);
					rowHead.getCell(3).setCellStyle(headerStyle);
					rowHead.getCell(4).setCellStyle(headerStyle);
					rowHead.getCell(5).setCellStyle(headerStyle);
					rowHead.getCell(6).setCellStyle(headerStyle);
					rowHead.getCell(7).setCellStyle(headerStyle);
					rowHead.getCell(8).setCellStyle(headerStyle);
					rowHead.setHeightInPoints(20);
				}

				String conceptoAgrupar = "";
				rowCount = 1;

				for (PreguntasExpediente preguntaExpedienteTabla : preguntasExpedienteTabla) {
					HSSFRow preguntaExpedienteRow = sheet.createRow(rowCount++);
					if (castellano) {
						conceptoAgrupar = preguntaExpedienteTabla.getDescripcionCastellano();
					} else if (euskera) {
						conceptoAgrupar = preguntaExpedienteTabla.getDescripcionEuskera();
					}

					preguntaExpedienteRow.createCell(0).setCellValue(conceptoAgrupar);
					preguntaExpedienteRow.getCell(0).setCellStyle(conceptoStyle);
					preguntaExpedienteRow.setHeightInPoints(20);
					sheet.addMergedRegion(new CellRangeAddress(preguntaExpedienteRow.getRowNum(),
							preguntaExpedienteRow.getRowNum(), 0, 8));
					preguntaExpedienteRow = sheet.createRow(rowCount++);

					if (preguntaExpedienteTabla.getFechaFactura() != null) {

						SimpleDateFormat sdf = new SimpleDateFormat();

						if (castellano) {
							sdf = new SimpleDateFormat(Constantes.FORMATO_FECHA_ES);
						} else if (euskera) {
							sdf = new SimpleDateFormat(Constantes.FORMATO_FECHA_EU);
						}

						String fechaComoCadena = sdf.format(preguntaExpedienteTabla.getFechaFactura());
						preguntaExpedienteRow.createCell(0).setCellValue(fechaComoCadena);
					} else {
						preguntaExpedienteRow.createCell(0).setCellValue("");
					}

					preguntaExpedienteRow.createCell(1).setCellValue(preguntaExpedienteTabla.getNumeroFactura());
					preguntaExpedienteRow.createCell(2).setCellValue(preguntaExpedienteTabla.getProveedor());
					preguntaExpedienteRow.createCell(3).setCellValue(preguntaExpedienteTabla.getImporteString());
					preguntaExpedienteRow.createCell(4)
							.setCellValue(preguntaExpedienteTabla.getImporteAdmitidoString());
					if (castellano) {
						preguntaExpedienteRow.createCell(5)
								.setCellValue(preguntaExpedienteTabla.getObservacionesTecnicoCas());
					} else if (euskera) {
						preguntaExpedienteRow.createCell(5)
								.setCellValue(preguntaExpedienteTabla.getObservacionesTecnicoEus());
					}
					preguntaExpedienteRow.createCell(6).setCellValue(preguntaExpedienteTabla.getResultado());
					preguntaExpedienteRow.createCell(7)
							.setCellValue(preguntaExpedienteTabla.getObservacionesInspeccionCas());
					preguntaExpedienteRow.createCell(8)
							.setCellValue(preguntaExpedienteTabla.getObservacionesInspeccionEus());
					preguntaExpedienteRow.createCell(9).setCellValue(preguntaExpedienteTabla.getIdPreguntaExpediente());
					preguntaExpedienteRow.createCell(10).setCellValue(Constantes.PREGUNTA_EXPEDIENTE_SIN_CONCEPTO);

					preguntaExpedienteRow.getCell(0).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(1).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(2).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(3).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(4).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(5).setCellStyle(preguntaStyle);
					preguntaExpedienteRow.getCell(6).setCellStyle(respuestaStyle);
					preguntaExpedienteRow.getCell(7).setCellStyle(respuestaStyle);
					preguntaExpedienteRow.getCell(8).setCellStyle(respuestaStyle);
					preguntaExpedienteRow.setHeightInPoints(20);

				}
			}

			// Creamos la fila cabecera de inspección, expediente y título
			HSSFRow rowHeadInspeccion = sheet2.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 = sheet2.createRow(1);
			rowInspeccion.createCell(0).setCellValue(identificadorInspeccion);
			rowInspeccion.createCell(1).setCellValue(folderNumber);
			rowInspeccion.createCell(2).setCellValue(titulo);
			List<OpcionesPrePro> opcionesPrePro = this.preguntasProtocoloDao.findOpcionesPrePro();

			// Creamos la fila cabecera de las preguntas de protocolo
			if (preguntasRespuestasProtocolo.size() > 0) {

				HSSFRow rowHeadPreguntasProtocolo = sheet2.createRow(2);
				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);
			}

			rowCount = 3;

			// 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 = sheet2.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 inspección, expediente y título
			rowHeadInspeccion = sheet3.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
			rowInspeccion = sheet3.createRow(1);
			rowInspeccion.createCell(0).setCellValue(identificadorInspeccion);
			rowInspeccion.createCell(1).setCellValue(folderNumber);
			rowInspeccion.createCell(2).setCellValue(titulo);

			// 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);

			if (preguntasRespuestasExpediente.size() > 0) {

				// Creamos la fila cabecera
				HSSFRow rowHead = sheet3.createRow(2);
				rowHead.createCell(0).setCellValue(
						appMessageSource.getMessage("excel.informeTecnico.preguntasExpediente", null, locale));
				rowHead.createCell(1)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.tipoPreguntas", null, locale));
				rowHead.createCell(2)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.respuestas", null, locale));
				rowHead.createCell(3)
						.setCellValue(appMessageSource.getMessage("excel.informeTecnico.opciones", null, locale));
				rowHead.getCell(0).setCellStyle(headerStyle);
				rowHead.getCell(1).setCellStyle(headerStyle);
				rowHead.getCell(2).setCellStyle(headerStyle);
				rowHead.getCell(3).setCellStyle(headerStyle);
				rowHead.setHeightInPoints(20);
			}

			rowCount = 3;

			// Creamos las filas con las preguntas del expediente
			for (PreguntasRespuestasExpediente preguntaRespuestaExpediente : preguntasRespuestasExpediente) {
				HSSFRow preguntaExpedienteRow = sheet3.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).setCellStyle(preguntaStyle);
							preguntaExpedienteRow.getCell(3).setCellValue(stringOpciones);
							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);
			sheet.autoSizeColumn(3);
			sheet.autoSizeColumn(4);
			sheet.autoSizeColumn(5);
			sheet.autoSizeColumn(6);
			sheet.autoSizeColumn(7);
			sheet.autoSizeColumn(8);
			sheet2.autoSizeColumn(0);
			sheet2.autoSizeColumn(1);
			sheet2.autoSizeColumn(2);
			if (!opcionesPrePro.isEmpty() || !opcionesPreExp.isEmpty()) {
				sheet2.autoSizeColumn(3);
			}
			sheet3.autoSizeColumn(0);
			sheet3.autoSizeColumn(1);
			sheet3.autoSizeColumn(2);
			if (!opcionesPreExp.isEmpty()) {
				sheet3.autoSizeColumn(3);
			}

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

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

			PreguntasExpedienteServiceImpl.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";
			}
			PreguntasExpedienteServiceImpl.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();

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

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

	}

	@Override
	public List<PreguntasExpediente> findAllLikeInformeTabla(PreguntasExpediente filterPreguntasExpediente,
			TableRequestDto tableRequestDto, boolean startsWith) {
		return this.preguntasExpedienteDao.findAllLikeInformeTabla(filterPreguntasExpediente, tableRequestDto,
				startsWith);
	}

	@Override
	public ListaPreguntasRespuestas importarExceltabla(MultipartFile excelAImportar) throws IOException {

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

		Locale locale = LocaleContextHolder.getLocale();

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

		// Cogemos la primera 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 primera hoja (preguntas de la tabla)
		for (Row respuestaTablaRow : sheet) {

			// Si es la fila cabecera o la fila concepto nos la saltamos
			if (respuestaTablaRow.getCell(0).getCellStyle().getFillForegroundColor() == HSSFColor.GREY_25_PERCENT.index
					|| sheet.getRow(0) == respuestaTablaRow) {
				continue;
			}

			PreguntasExpediente preguntaExpediente = new PreguntasExpediente();

			RespuestasExpediente respuestaExpediente = new RespuestasExpediente();
			PreguntasRespuestasExpediente preguntaRespuestaExpediente = new PreguntasRespuestasExpediente();

			// Recogemos los valores que necesitamos
			String conceptoCell = dataFormatter.formatCellValue(respuestaTablaRow.getCell(10));
			String resultadoCell = "";
			String observacionesCasCell = "";
			String observacionesEusCell = "";

			if (Integer.parseInt(conceptoCell) == Constantes.PREGUNTA_EXPEDIENTE_CON_CONCEPTO) {
				resultadoCell = dataFormatter.formatCellValue(respuestaTablaRow.getCell(4));
				observacionesCasCell = dataFormatter.formatCellValue(respuestaTablaRow.getCell(5));
				observacionesEusCell = dataFormatter.formatCellValue(respuestaTablaRow.getCell(6));
			} else if (Integer.parseInt(conceptoCell) == Constantes.PREGUNTA_EXPEDIENTE_SIN_CONCEPTO) {
				resultadoCell = dataFormatter.formatCellValue(respuestaTablaRow.getCell(6));
				observacionesCasCell = dataFormatter.formatCellValue(respuestaTablaRow.getCell(7));
				observacionesEusCell = dataFormatter.formatCellValue(respuestaTablaRow.getCell(8));
			}

			String idPreguntaExpedienteCell = dataFormatter.formatCellValue(respuestaTablaRow.getCell(9));
			preguntaExpediente.setIdPreguntaExpediente(Integer.parseInt(idPreguntaExpedienteCell));

			respuestaExpediente.setPreguntaExpediente(preguntaExpediente);
			preguntaExpediente.setIdTipoPregunta(Constantes.TIPO_PREGUNTA_CORRECTO_INCORRECTO);
			respuestaExpediente.setRespuesta(resultadoCell);
			respuestaExpediente.setObservacionesInspeccionCas(observacionesCasCell);
			respuestaExpediente.setObservacionesInspeccionEus(observacionesEusCell);
			preguntaRespuestaExpediente.setPreguntasExpediente(preguntaExpediente);
			preguntaRespuestaExpediente.setRespuestasExpediente(respuestaExpediente);

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

		}

		// Cogemos la segunda hoja
		HSSFSheet sheet2 = workbook.getSheetAt(1);

		// Iteramos sobre las filas de la segunda hoja (preguntas del protocolo)
		for (Row respuestaProtocoloRow : sheet2) {

			// Si es la fila cabecera nos la saltamos
			if (sheet2.getRow(0) == respuestaProtocoloRow || sheet2.getRow(1) == respuestaProtocoloRow
					|| sheet2.getRow(2) == respuestaProtocoloRow) {
				continue;
			}

			if (Constantes.TIPO_PREGUNTA_TITULO != Integer
					.parseInt(dataFormatter.formatCellValue(respuestaProtocoloRow.getCell(5)))) {

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

				// Recogemos los valores que necesitamos
				String respuestaCell = dataFormatter.formatCellValue(respuestaProtocoloRow.getCell(2));
				String idRelProPreCell = dataFormatter.formatCellValue(respuestaProtocoloRow.getCell(4));
				String idTipoPreguntaCell = dataFormatter.formatCellValue(respuestaProtocoloRow.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 = respuestaProtocoloRow.getCell(2).getDateCellValue();
						respuestaCell = formatoFecha.format(fecha);
					} catch (Exception e) {
						PreguntasExpedienteServiceImpl.logger.error(e.getMessage());
						respuestaCell = dataFormatter.formatCellValue(respuestaProtocoloRow.getCell(2));
					}
				}

				if (Integer.parseInt(idTipoPreguntaCell) == Constantes.TIPO_PREGUNTA_CHECKBOX
						&& !"".equals(dataFormatter.formatCellValue(respuestaProtocoloRow.getCell(6)))) {
					String opcionesIds = dataFormatter.formatCellValue(respuestaProtocoloRow.getCell(6));
					String opcionesDesc = dataFormatter.formatCellValue(respuestaProtocoloRow.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(respuestaProtocoloRow.getRowNum() + 1);
					preguntasRespuestasProtocolo.add(preguntaRespuestaErrorPro);
				} else {
					preguntasRespuestasProtocolo.add(preguntaRespuestaProtocolo);
				}

			}
		}

		// Cogemos la tercera hoja
		HSSFSheet sheet3 = workbook.getSheetAt(2);

		// Iteramos sobre las filas de la tercera hoja (preguntas del
		// expediente)
		for (Row respuestaExpedienteRow : sheet3) {

			// Si es la fila cabecera nos la saltamos
			if (sheet3.getRow(0) == respuestaExpedienteRow || sheet3.getRow(1) == respuestaExpedienteRow
					|| sheet3.getRow(2) == respuestaExpedienteRow) {
				continue;
			}

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

				// Recogemos los valores que necesitamos
				String respuestaCell = dataFormatter.formatCellValue(respuestaExpedienteRow.getCell(2));
				String idPreguntaExpedienteCell = dataFormatter.formatCellValue(respuestaExpedienteRow.getCell(4));
				String idTipoPreguntaCell = dataFormatter.formatCellValue(respuestaExpedienteRow.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 = respuestaExpedienteRow.getCell(2).getDateCellValue();
						respuestaCell = formatoFecha.format(fecha);
					} catch (Exception e) {
						PreguntasExpedienteServiceImpl.logger.error(e.getMessage());
						respuestaCell = dataFormatter.formatCellValue(respuestaExpedienteRow.getCell(2));
					}
				}

				if (Integer.parseInt(idTipoPreguntaCell) == Constantes.TIPO_PREGUNTA_CHECKBOX
						&& !"".equals(dataFormatter.formatCellValue(respuestaExpedienteRow.getCell(6)))) {
					String opcionesIds = dataFormatter.formatCellValue(respuestaExpedienteRow.getCell(6));
					String opcionesDesc = dataFormatter.formatCellValue(respuestaExpedienteRow.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(respuestaExpedienteRow.getRowNum() + 1);
					preguntasRespuestasExpediente.add(preguntaRespuestaErrorExpediente);
				} else {
					preguntasRespuestasExpediente.add(preguntaRespuestaExpediente);
				}

			}

		}

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

		return listaPreguntasRespuestas;
	}

	@Override
	public void eliminarPreguntaExpediente(PreguntasExpediente preguntaExpediente) {
		// Eliminar las opciones asociadas a esa pregunta
		this.opcionesPreExpDao.removeByIdPreguntaExpediente(preguntaExpediente);
		// Eliminar las respuestas asociadas a esa pregunta
		this.respuestasExpedienteService.removeRespuestaFicheros(preguntaExpediente);
		// Eliminar la pregunta
		this.preguntasExpedienteDao.remove(preguntaExpediente);
	}

	@Override
	public List<OpcionesPreExp> findOpcionesPreExp() {
		return this.preguntasExpedienteDao.findOpcionesPreExp();
	}
}
