package com.ruoyi.project.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hslf.usermodel.HSLFShape;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFTextShape;
import org.apache.poi.hssf.usermodel.HSSFCell;
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.hwpf.HWPFDocument;
import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFShape;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTextShape;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;

@Component
public class DocumentUtil {
    private static final Map<String, String> FILE_TYPE_MAP = new HashMap<>();
    static {
        FILE_TYPE_MAP.put("FFD8FF", "jpg");
        FILE_TYPE_MAP.put("89504E47", "png");
        FILE_TYPE_MAP.put("47494638", "gif");
        FILE_TYPE_MAP.put("424D", "bmp");
        FILE_TYPE_MAP.put("49492A00", "tif");
        FILE_TYPE_MAP.put("4D4D002A", "tif");
        FILE_TYPE_MAP.put("52494646", "webp");
        FILE_TYPE_MAP.put("25504446", "pdf");
        FILE_TYPE_MAP.put("504B0304", "zip or office (docx, xlsx, pptx)");
        FILE_TYPE_MAP.put("D0CF11E0", "office (doc, xls, ppt)");
        // WPS文件魔数
        FILE_TYPE_MAP.put("D0CF11E0A1B11AE1", "wps"); // WPS文档
        FILE_TYPE_MAP.put("504B030414000600", "wpsx"); // WPS新格式
//        FILE_TYPE_MAP.put("52617221", "rar");
        FILE_TYPE_MAP.put("526172211C07", "rar5");
        FILE_TYPE_MAP.put("526172211A07", "rar");
        FILE_TYPE_MAP.put("377ABCAF271C", "7z");
        FILE_TYPE_MAP.put("74686573", "txt");  // 以 "the" 开头的文本文件
        FILE_TYPE_MAP.put("8A9DE0D14725E20B7A74", "jiami");  // 以 "the" 开头的文本文件
    }

    public String getFileTypeByMagicNumber(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(b & 0xFF).toUpperCase();
            if (hex.length() == 1) {
                hexString.append("0");
            }
            hexString.append(hex);
        }

        // 判断是否为 RAR 格式
        if (hexString.toString().startsWith("52617221")) {
            // 如果是以 "52617221" 开头，则进一步检查是否为 RAR5
            if (hexString.toString().startsWith("526172211A0701")) {
                return "rar5";  // RAR5 格式
            } else {
                return "rar";   // 普通 RAR 格式
            }
        }

        // 检查WPS文件
        if (hexString.toString().startsWith("D0CF11E0A1B11AE1")) {
            return "wps";
        }
        if (hexString.toString().startsWith("504B030414000600")) {
            return "wpsx";
        }

        for (Map.Entry<String, String> entry : FILE_TYPE_MAP.entrySet()) {
            if (hexString.toString().startsWith(entry.getKey())) {
                return entry.getValue();
            }
        }

        if (hexString.toString().matches("[0-9A-Fa-f]*") && hexString.length() > 0) {
            // 若符合文本文件的条件（只包含ASCII字符），认为是txt文件
            return "txt";
        }

        return null;
    }

    public String checkZipOrOfficeFile(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        if (fileName != null) {
            if (fileName.endsWith(".xlsx")) return "xlsx";
            if (fileName.endsWith(".docx")) return "docx";
            if (fileName.endsWith(".pptx")) return "pptx";
            if (fileName.endsWith(".zip")) return "zip";
            // WPS文件扩展名
            if (fileName.endsWith(".wps")) return "wps";
            if (fileName.endsWith(".et")) return "et";  // WPS表格
            if (fileName.endsWith(".dps")) return "dps"; // WPS演示
            if (fileName.endsWith(".wpt")) return "wpt"; // WPS模板
        }
        return "unknown zip format";
    }

    public String checkLegacyOfficeFile(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        if (fileName != null) {
            if (fileName.endsWith(".xls")) return "xls";
            if (fileName.endsWith(".doc")) return "doc";
            if (fileName.endsWith(".ppt")) return "ppt";
            // WPS旧格式文件
            if (fileName.endsWith(".wps")) return "wps";
            if (fileName.endsWith(".et")) return "et";
            if (fileName.endsWith(".dps")) return "dps";
        }
        return "unknown office format";
    }

    public String extractContent(String fileType, InputStream inputStream) throws IOException {
        String content = "";
        if (fileType.equals("doc")) {
            content = extractDocContent(inputStream);
        } else if (fileType.equals("docx")) {
            content = extractDocxContent(inputStream);
        } else if (fileType.equals("txt")) {
            content = extractTxtContent(inputStream);
        }  else if (fileType.equals("pdf")) {
            content = extractPDFContent(inputStream);
        } else if (fileType.equals("xls")) {
            content = extractXLSContent(inputStream);
        } else if (fileType.equals("xlsx")) {
            content = extractXLSXContent(inputStream);
        } else if (fileType.equals("ppt")) {
            content = extractPPTContent(inputStream);
        } else if (fileType.equals("pptx")) {
            content = extractPPTXContent(inputStream);
        } else if (fileType.equals("wps") || fileType.equals("wpt")) {
            // WPS文档文件，使用doc处理方式
            content = extractWPSContent(inputStream);
        } else if (fileType.equals("et")) {
            // WPS表格文件，使用xls处理方式
            content = extractWPSETContent(inputStream);
        } else if (fileType.equals("dps")) {
            // WPS演示文件，使用ppt处理方式
            content = extractWPSDPSContent(inputStream);
        } else if (fileType.equals("wpsx")) {
            // WPS新格式文件，使用docx处理方式
            content = extractWPSXContent(inputStream);
        } else {
            System.out.println("Unsupported file format: " + fileType);
        }
        return content;
    }

    /**
     * 智能提取文件内容，优先根据扩展名判断
     */
    public String smartExtractContent(MultipartFile file, String fileType) throws IOException {
        String fileName = file.getOriginalFilename();

        // 优先根据扩展名判断
        if (fileName != null) {
            String lowerFileName = fileName.toLowerCase();

            // 处理Excel文件
            if (lowerFileName.endsWith(".xlsx")) {
                try (InputStream inputStream = file.getInputStream()) {
                    return extractXLSXContent(inputStream);
                }
            } else if (lowerFileName.endsWith(".xls")) {
                // 如果是.xls文件，即使魔数识别为wps，也尝试按xls处理
                try (InputStream inputStream = file.getInputStream()) {
                    return extractXLSContent(inputStream);
                } catch (Exception e) {
                    // 如果按xls处理失败，且魔数识别为wps，则尝试按wps表格处理
                    if ("wps".equals(fileType)) {
                        try (InputStream inputStream = file.getInputStream()) {
                            return extractWPSETContent(inputStream);
                        }
                    }
                    throw e;
                }
            } else if (lowerFileName.endsWith(".et")) {
                // WPS表格文件
                try (InputStream inputStream = file.getInputStream()) {
                    return extractWPSETContent(inputStream);
                }
            }

            // 处理其他文件
            try (InputStream inputStream = file.getInputStream()) {
                return extractContent(fileType, inputStream);
            }
        }

        // 如果没有扩展名，按原逻辑处理
        try (InputStream inputStream = file.getInputStream()) {
            return extractContent(fileType, inputStream);
        }
    }

    /**
     * 提取WPS文档内容（.wps, .wpt格式）
     */
    public String extractWPSContent(InputStream inputStream) {
        StringBuilder extractedText = new StringBuilder();
        try {
            // WPS文档格式与Microsoft Word的.doc格式类似，可以使用HWPFDocument处理
            HWPFDocument doc = new HWPFDocument(inputStream);
            extractedText.append(doc.getDocumentText()).append("\n");

            // 尝试获取文档属性信息
            try {
                SummaryInformation summaryInfo = doc.getSummaryInformation();
                if (summaryInfo != null) {
                    if (summaryInfo.getTitle() != null) {
                        extractedText.append("标题: ").append(summaryInfo.getTitle()).append("\n");
                    }
                    if (summaryInfo.getAuthor() != null) {
                        extractedText.append("作者: ").append(summaryInfo.getAuthor()).append("\n");
                    }
                }
            } catch (Exception e) {
                // 忽略属性获取异常
                System.out.println("获取WPS文档属性失败: " + e.getMessage());
            }

        } catch (Exception e) {
            System.err.println("处理WPS文档时出错: " + e.getMessage());
            // 如果标准方法失败，尝试使用备用方法
            extractedText.append(extractWPSContentAlternative(inputStream));
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
    }

    /**
     * 备用方法：处理WPS文档内容
     */
    private String extractWPSContentAlternative(InputStream inputStream) {
        StringBuilder extractedText = new StringBuilder();
        try {
            // 重新读取流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) > -1) {
                baos.write(buffer, 0, len);
            }
            baos.flush();

            byte[] fileBytes = baos.toByteArray();
            String content = new String(fileBytes, "ISO-8859-1");

            // 尝试提取文本内容（简单实现）
            // WPS文件通常包含可读文本，可以通过正则表达式提取
            String textContent = content.replaceAll("[^\\x20-\\x7E\\x0A\\x0D\\u4E00-\\u9FA5]", " ");
            extractedText.append(textContent);

        } catch (Exception e) {
            System.err.println("备用方法处理WPS文档失败: " + e.getMessage());
        }
        return extractedText.toString();
    }

    /**
     * 提取WPS表格内容（.et格式）
     */
    public String extractWPSETContent(InputStream inputStream) {
        StringBuilder extractedText = new StringBuilder();
        try {
            // WPS表格格式与Microsoft Excel的.xls格式类似，可以使用HSSFWorkbook处理
            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
            for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
                HSSFSheet sheet = workbook.getSheetAt(sheetIndex);
                extractedText.append("工作表: ").append(sheet.getSheetName()).append("\n");

                for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                    HSSFRow row = sheet.getRow(rowIndex);
                    if (row != null) {
                        for (int cellIndex = 0; cellIndex < row.getLastCellNum(); cellIndex++) {
                            HSSFCell cell = row.getCell(cellIndex);
                            if (cell != null) {
                                switch (cell.getCellType()) {
                                    case STRING:
                                        extractedText.append(cell.getStringCellValue()).append("\t");
                                        break;
                                    case NUMERIC:
                                        extractedText.append(cell.getNumericCellValue()).append("\t");
                                        break;
                                    case BOOLEAN:
                                        extractedText.append(cell.getBooleanCellValue()).append("\t");
                                        break;
                                    case FORMULA:
                                        extractedText.append(cell.getCellFormula()).append("\t");
                                        break;
                                    default:
                                        extractedText.append(" \t");
                                        break;
                                }
                            }
                        }
                        extractedText.append("\n");
                    }
                }
                extractedText.append("\n");
            }
        } catch (Exception e) {
            System.err.println("处理WPS表格时出错: " + e.getMessage());
            // 备用方法
            extractedText.append(extractWPSETContentAlternative(inputStream));
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
    }

    /**
     * 备用方法：处理WPS表格内容
     */
    private String extractWPSETContentAlternative(InputStream inputStream) {
        // 对于WPS表格，如果标准方法失败，可以尝试使用文本提取
        return "无法解析WPS表格文件内容，请确保文件格式正确。";
    }

    /**
     * 提取WPS演示内容（.dps格式）
     */
    public String extractWPSDPSContent(InputStream inputStream) {
        StringBuilder extractedText = new StringBuilder();
        try {
            // WPS演示格式与Microsoft PowerPoint的.ppt格式类似，可以使用HSLFSlideShow处理
            HSLFSlideShow ppt = new HSLFSlideShow(inputStream);

            for (HSLFSlide slide : ppt.getSlides()) {
                extractedText.append("幻灯片 ").append(slide.getSlideNumber()).append(":\n");

                for (HSLFShape shape : slide.getShapes()) {
                    if (shape instanceof HSLFTextShape) {
                        HSLFTextShape textShape = (HSLFTextShape) shape;
                        extractedText.append(textShape.getText()).append("\n");
                    }
                }
                extractedText.append("\n");
            }
        } catch (Exception e) {
            System.err.println("处理WPS演示时出错: " + e.getMessage());
            // 备用方法
            extractedText.append(extractWPSDPSContentAlternative(inputStream));
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
    }

    /**
     * 备用方法：处理WPS演示内容
     */
    private String extractWPSDPSContentAlternative(InputStream inputStream) {
        // 对于WPS演示文件，如果标准方法失败，返回提示信息
        return "无法解析WPS演示文件内容，请确保文件格式正确。";
    }

    /**
     * 提取WPS新格式内容（.wpsx格式）
     */
    public String extractWPSXContent(InputStream inputStream) {
        StringBuilder extractedText = new StringBuilder();
        try {
            // WPS新格式与Microsoft Word的.docx格式类似，可以使用XWPFDocument处理
            XWPFDocument docx = new XWPFDocument(inputStream);

            // 提取段落文本
            for (XWPFParagraph paragraph : docx.getParagraphs()) {
                extractedText.append(paragraph.getText());
                extractedText.append("</br>");
            }

            // 提取表格文本
            for (XWPFTable table : docx.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        extractedText.append(cell.getText()).append("&nbsp;&nbsp;&nbsp;&nbsp;");
                    }
                    extractedText.append("</br>");
                }
            }

        } catch (Exception e) {
            System.err.println("处理WPS新格式文档时出错: " + e.getMessage());
            // 备用方法
            extractedText.append(extractWPSXContentAlternative(inputStream));
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
    }

    /**
     * 备用方法：处理WPS新格式内容
     */
    private String extractWPSXContentAlternative(InputStream inputStream) {
        // 对于WPS新格式文件，如果标准方法失败，返回提示信息
        return "无法解析WPS新格式文档内容，请确保文件格式正确。";
    }

    public String extractPPTXContent(InputStream inputStream) {
        StringBuilder extractedText = new StringBuilder();
        try {
            XMLSlideShow pptx = new XMLSlideShow(inputStream);

            for (XSLFSlide slide : pptx.getSlides()) {
                for (XSLFShape shape : slide.getShapes()) {
                    if (shape instanceof XSLFTextShape) {
                        XSLFTextShape textShape = (XSLFTextShape) shape;
                        extractedText.append(textShape.getText()+"\n");
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
    }
    // 提取 .ppt 文件的文本内容
    public String extractPPTContent(InputStream inputStream) {
        StringBuilder extractedText = new StringBuilder();
        try {
            HSLFSlideShow ppt = new HSLFSlideShow(inputStream);

            for (HSLFSlide slide : ppt.getSlides()) {
                // 遍历幻灯片中的所有形状
                for (HSLFShape shape : slide.getShapes()) {
                    extractedText.append(slide.getSlideNumber() + "\n");
                    if (shape instanceof HSLFTextShape) {
                        HSLFTextShape textShape = (HSLFTextShape) shape;
                        extractedText.append(textShape.getText() + "\n");
                    }
                }
                extractedText.append("\n");
            }
            //jsonObject.put("content",extractedText.toString());
            return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return "";
    }
    public String extractXLSXContent(InputStream inputStream) {
        StringBuilder extractedText = new StringBuilder();
        try{
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            // 遍历每个工作表
            for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
                XSSFSheet sheet = workbook.getSheetAt(sheetIndex);
                extractedText.append(sheet.getSheetName() + "\n");
                // 遍历每一行
                for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                    XSSFRow row = sheet.getRow(rowIndex);

                    if (row != null) {
                        // 遍历每个单元格
                        for (int cellIndex = 0; cellIndex < row.getLastCellNum(); cellIndex++) {
                            XSSFCell cell = row.getCell(cellIndex);
                            if (cell != null) {
                                // 获取单元格内容
                                switch (cell.getCellType()) {
                                    case STRING:
                                        extractedText.append(cell.getStringCellValue() + "\t");
                                        break;
                                    case NUMERIC:
                                        extractedText.append(cell.getNumericCellValue() + "\t");
                                        break;
                                    case BOOLEAN:
                                        extractedText.append(cell.getBooleanCellValue() + "\t");
                                        break;
                                    case FORMULA:
                                        extractedText.append(cell.getCellFormula() + "\t");
                                        break;
                                    default:
                                        extractedText.append(" \t");
                                        break;
                                }
                            }
                        }
                        extractedText.append("\n");
                    }
                }
                extractedText.append("\n");
            }
            //
//            return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
            return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("&nbsp;", "");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return "";
    }

    public String extractXLSContent(InputStream inputStream) {
        StringBuilder extractedText = new StringBuilder();
        try{
            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
            for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
                HSSFSheet sheet = workbook.getSheetAt(sheetIndex);
                extractedText.append((sheet.getSheetName() + "\n"));
                // 遍历每一行
                for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                    HSSFRow row = sheet.getRow(rowIndex);
                    if (row != null) {
                        // 遍历每个单元格
                        for (int cellIndex = 0; cellIndex < row.getLastCellNum(); cellIndex++) {
                            HSSFCell cell = row.getCell(cellIndex);
                            if (cell != null) {
                                // 获取单元格内容
                                switch (cell.getCellType()) {
                                    case STRING:
                                        extractedText.append((cell.getStringCellValue() + "\t"));
                                        break;
                                    case NUMERIC:
                                        extractedText.append(cell.getNumericCellValue() + "\t");
                                        break;
                                    case BOOLEAN:
                                        extractedText.append(cell.getBooleanCellValue() + "\t");
                                        break;
                                    case FORMULA:
                                        extractedText.append(cell.getCellFormula() + "\t");
                                        break;
                                    default:
                                        extractedText.append(" \t");
                                        break;
                                }
                            }
                        }
                        extractedText.append("\n");
                    }
                }
                extractedText.append("\n");
            }
//            return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
            return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("&nbsp;", "");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return "";
    }

    private String extractPDFContent(InputStream inputStream) throws IOException {
        StringBuilder extractedText = new StringBuilder();

        //ocr
        try (PDDocument document = PDDocument.load(inputStream)) {
            PDFTextStripper pdfStripper = new PDFTextStripper();
            String textContent = pdfStripper.getText(document);
            extractedText.append(textContent).append("\n");
            // 关闭 PDF 文档
            document.close();
            return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
        } catch (Exception e) {
            throw new IOException(e);
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }


    public String extractTxtContent(InputStream inputStream) {
        StringBuilder content = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                content.append(line).append("\n");  // 每行内容添加换行符
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return content.toString();
    }

    // Method for extracting .doc content
    private String extractDocContent(InputStream inputStream) throws IOException {
        try {
            StringBuilder extractedText = new StringBuilder();
            HWPFDocument doc = new HWPFDocument(inputStream);
            extractedText.append(doc.getDocumentText()).append("\n");
            return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    // Method for extracting .docx content (text and images)
    private String extractDocxContent(InputStream inputStream) throws IOException {
        try {
            StringBuilder extractedText = new StringBuilder();
            XWPFDocument docx = new XWPFDocument(inputStream);
            for (XWPFParagraph paragraph : docx.getParagraphs()) {
                extractedText.append(paragraph.getText());
                extractedText.append("</br>");
            }
            for (XWPFTable table : docx.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
//                        extractedText.append(cell.getText()).append("\t");
                        extractedText.append(cell.getText()).append("&nbsp;&nbsp;&nbsp;&nbsp;");
                    }
                    extractedText.append("</br>");
                }
            }
            return extractedText.toString().replaceAll("\\r?\\n", "</br>").replaceAll("\\t", "&nbsp;&nbsp;&nbsp;&nbsp;");

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }
}