maven

		<dependency>
			<groupId>org.apache.tika</groupId>
			<artifactId>tika-parsers</artifactId>
			<version>1.18</version>
			<exclusions>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

FileDetect

public class FileDetect implements Detector {
	
	private Tika tika = new Tika();	

	@Override
	public MediaType detect(InputStream input, Metadata metadata){
		Map<String, String> map=new HashMap<>();
		String message="";
		
		if(metadata.get(BasicMeta.File_PATH)==null){
			message="Source of meta not found";
			map.put(BasicMeta.File_UNKNOWN_ERROR, message);
			return new MediaType("file","unknown",map);
		}
		try {
			Path source = Paths.get(metadata.get(BasicMeta.File_PATH));			
			String mediaType = tika.detect(input, metadata);			
			if ("application/xml".equals(mediaType)) {
				validCharset(source);
				XmlDetect detect = new XmlDetect();
				return detect.detect(source);
			} else if ("application/x-tika-msoffice".equals(mediaType)
					|| "application/vnd.ms-excel".equals(mediaType)) {
				
				return detect.detect(source);
			} else if ("application/x-tika-ooxml".equals(mediaType)
					|| "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equals(mediaType)) {
				
				return detect.detect(source);
			} else if ("text/plain".equals(mediaType)) {
				validCharset(source);
					
				return detect.detect(source);
			} else if ("text/csv".equals(mediaType)) {
				validCharset(source);
				
				return detect.detect(source);
			}
		}catch(Exception e){			
			message=foundCause(e).getMessage();	
			if(message==null){
				message="NullPointerException";
			}
		}
				
		map.put(BasicMeta.File_UNKNOWN_ERROR, message);
		return new MediaType("file","unknown",map);
	}
	
	private Throwable foundCause(Throwable t){
		if(t.getCause()!=null){
			return foundCause(t.getCause());
		}else{
			return t;
		}
	}
	
	private void validCharset(Path source) throws IOException {
		CharsetDetector det = new CharsetDetector();
		try (InputStream in = Files.newInputStream(source)) {			
			BOMInputStream bom=new BOMInputStream(new BufferedInputStream(in));
			det = det.setText(bom);			
			String c = det.detect().getName();	
			if(bom.hasBOM()){
				throw new RuntimeException("BOM");
			}else{
				if(!("ISO-8859-1".equals(c) || "UTF-8".equals(c))){
					throw new RuntimeException(c);
				}
			}
		}		
	}
}

BaseDetect

public class BaseDetect {

	 Throwable foundCause(Throwable t){
		if(t.getCause()!=null){
			return foundCause(t.getCause());
		}else{
			return t;
		}
	}
	
	 public MediaType detect(Path source){
			String message="";
			try {
				return doDetect(source);
			} catch (Exception e) {			
				e.printStackTrace();
				message=foundCause(e).getMessage();
				if(message==null){
					message="NullPointerException";
				}
			}
			
			Map<String, String> map=new HashMap<>();
			map.put(BasicMeta.FILE_UNKNOWN_ERROR, message);
			return new MediaType("datafeed","unknown",map);
		}
	 
	/**
	 * Overwrite this function
	 * @param source  source of path
	 * @return {@link MediaType}
	 * @throws Exception
	 */
	MediaType doDetect(Path source) throws Exception{
		return new MediaType("datafeed","unknown");
	}
}

Detect use parser

Base Parser

public abstract class AbstractParser implements Parser{

	
	protected Metadata metadata = new Metadata();
	protected ParseContext contex=new ParseContext();
	
	public void parse(Path source) throws IOException, SAXException, TikaException{
		try(InputStream in=Files.newInputStream(source)){
			parse(in, null, metadata, contex);
		}
	}
	
	public Metadata getMetadata(){
		return this.metadata;
	}
	
	public String version(){
		return this.metadata.get(BasicMeta.VERSION);
	}
	
	public boolean isType(){
		return this.metadata.get(BasicMeta.CONTENT_TYPE)!=null ?true:false;
	}
}

Sample parser

public class SampleParse extends AbstractParser {
    
 protected static final Set<MediaType> SUPPORTED_TYPES =
         Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
         		new MediaType("sample","xlsx"),
                 MediaType.application("vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
                 MediaType.application("vnd.ms-excel.sheet.macroenabled.12"),
                 MediaType.application("vnd.openxmlformats-officedocument.spreadsheetml.template"),
                 MediaType.application("vnd.ms-excel.template.macroenabled.12"),
                 MediaType.application("vnd.ms-excel.addin.macroenabled.12"),
                 MediaType.application("vnd.ms-excel.sheet.binary.macroenabled.12"),
                 MediaType.application("x-tika-ooxml")
                 )));
	
	@Override
	public Set<MediaType> getSupportedTypes(ParseContext context) {		
		return SUPPORTED_TYPES;
	}

	@Override
	public void parse(InputStream stream, ContentHandler handler, Metadata metadata, ParseContext context)
			throws IOException, SAXException, TikaException {
		Extract extract=new Extract();
		extract.process(stream);
		if(extract.getHeaderList().size()>5){				
			if(extract.getHeaderList().contains("A")){
				this.metadata.add(Meta.VERSION,"1.0");
				this.metadata.add(Meta.CONTENT_TYPE,Meta.XLSX);
			}
		}
	}
}

Parser use extractor

BaseExtractor

public class XlsxBase implements SheetContentsHandler{

	private List<String> sheetNameList = new ArrayList<>();
	private List<String> headerList = new ArrayList<>();
	private List<String> metaList = new ArrayList<>();
	private List<String> targetSheetNames;
	private int processedRow=-1;
	
	protected int headerLine=1;
	protected int metaLine=0;
	
	
	
	public XlsxBase(String sheetName){
		targetSheetNames=Arrays.asList(sheetName);
	}
	
	@Override
	public void startRow(int rowNum) {
		processedRow=rowNum;
	}

	@Override
	public void endRow(int rowNum) {		
		if(rowNum>=maxLine())
			throw new RuntimeException("Normal Stop");			
	}

	@Override
	public void cell(String cellReference, String formattedValue, XSSFComment comment) {
		if(processedRow==headerLine){
			headerList.add(formattedValue);
		}else if(processedRow==metaLine){
			metaList.add(formattedValue);
		}
	}

	@Override
	public void headerFooter(String text, boolean isHeader, String tagName) {		
		
	}


    public void processSheet(
            StylesTable styles,
            ReadOnlySharedStringsTable strings,
            SheetContentsHandler sheetHandler, 
            InputStream sheetInputStream) throws SAXException, ParserConfigurationException, IOException {
    	DataFormatter formatter = new DataFormatter();
        InputSource sheetSource = new InputSource(new BufferedInputStream(sheetInputStream,1024*1024));
        XMLReader sheetParser = SAXHelper.newXMLReader();
        InnerXmlHandler handler = new InnerXmlHandler(
              styles, null, strings, sheetHandler, formatter, false);
        sheetParser.setContentHandler(handler);
        sheetParser.setErrorHandler(handler);
        try{
        	sheetParser.parse(sheetSource);
        }catch(SAXException e){
        	if(!e.getMessage().equals("Normal Stop"))
        		throw e;
        }
    }

    public void process(InputStream stream) throws IOException{    	
		try {
			@Cleanup
			OPCPackage opcp = OPCPackage.open(stream);
			ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(opcp);
			XSSFReader xssfReader = new XSSFReader(opcp);
	        StylesTable styles = xssfReader.getStylesTable();        
	        XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
	        while (iter.hasNext()){
	        	try (InputStream in = iter.next()){
	        		String sheetName=iter.getSheetName();
	        		sheetNameList.add(sheetName);
	        		if(targetSheetNames.contains(sheetName)){
	        			processSheet(styles, strings, this, in);
	        		}
	        	}
	        }
		}catch (InvalidFormatException e) {
			e.printStackTrace();
		}catch (SAXException e) {
			e.printStackTrace();
		}catch (OpenXML4JException e){
			e.printStackTrace();
		}catch(ParserConfigurationException e){
			e.printStackTrace();
		}
		
    }
    
	public void process(Path source) throws IOException{
		try(InputStream in=Files.newInputStream(source)){
			process(in);
		}
	}
	
	public List<String> getSheetNameList() {
		return sheetNameList;
	}

	public List<String> getHeaderList() {
		return headerList;
	}

	public List<String> getMetaList() {
		return metaList;
	}
	
	private int maxLine(){
		return Math.max(headerLine, metaLine);
	}
	
	private class InnerXmlHandler extends XSSFSheetXMLHandler {
		
		public InnerXmlHandler(StylesTable styles, CommentsTable comments, ReadOnlySharedStringsTable strings,
				SheetContentsHandler sheetContentsHandler, DataFormatter dataFormatter, boolean formulasNotResults) {
			super(styles, comments, strings, sheetContentsHandler, dataFormatter, formulasNotResults);
		}
		
		@Override
		public void endElement(String uri, String localName, String qName) throws SAXException {
			try{
				super.endElement(uri, localName, qName);
			}catch(RuntimeException e){
				if(e.getMessage().equals("Normal Stop"))
					this.fatalError(new SAXParseException("Normal Stop", "", "", 0, 0));
			}			
		}

		@Override
		public void fatalError(SAXParseException e) throws SAXException {			
				throw e;			
		}
	
	}
}