package com.iformall.utils;

import cn.afterturn.easypoi.word.WordExportUtil;
import com.iformall.domain.vo.WordDocTableVo;
import org.apache.commons.io.FileUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

public class WordUtil {

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

    /**
     * 导出word
     * <p>第一步生成替换后的word文件，只支持docx</p>
     * <p>第二步下载生成的文件</p>
     * <p>第三步删除生成的临时文件</p>
     * 模版变量中变量格式：{{foo}}
     *
     * @param templatePath word模板地址
     * @param temDir       生成临时文件存放地址
     * @param fileName     文件名
     * @param params       替换的参数
     * @param request      HttpServletRequest
     * @param response     HttpServletResponse
     */
    public static void exportWord(String templatePath, String temDir, String fileName, String exportFileName, Map<String, Object> params, HttpServletRequest request, HttpServletResponse response, WordDocTableVo wordDocTableVo) {
        Assert.notNull(templatePath, "模板路径不能为空");
        Assert.notNull(temDir, "临时文件路径不能为空");
        Assert.notNull(exportFileName, "导出文件名不能为空");
        Assert.isTrue(exportFileName.endsWith(".docx"), "word导出请使用docx格式");
        if (!temDir.endsWith("/")) {
            temDir = temDir + File.separator;
        }
        File dir = new File(temDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        try {
//            String userAgent = request.getHeader("user-agent").toLowerCase();
//            if (userAgent.contains("msie") || userAgent.contains("like gecko")) {
//                exportFileName = URLEncoder.encode(exportFileName, "UTF-8");
//            } else {
//                exportFileName = new String(exportFileName.getBytes("utf-8"), "ISO-8859-1");
//            }


            XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);
            if(wordDocTableVo != null)
                insertValueToTable(doc,wordDocTableVo);

            String tmpPath = temDir + fileName;
            FileOutputStream fos = new FileOutputStream(tmpPath);
            doc.write(fos);
            // 设置强制下载不打开
            response.setContentType("application/force-download");
            // 设置文件名
            response.addHeader("Content-Disposition", "attachment;fileName=" + exportFileName);
            String userAgent = request.getHeader("user-agent");
            if (userAgent.contains("Firefox")) {
                response.setHeader("Content-disposition",
                        "attachment; filename="
                                + new String(exportFileName.getBytes("GB2312"),
                                "ISO-8859-1"));
            } else {
                response
                        .setHeader("Content-disposition",
                                "attachment; filename="
                                        + java.net.URLEncoder.encode(exportFileName,
                                        "UTF-8"));
            }
            OutputStream out = response.getOutputStream();
            doc.write(out);
            out.close();
            FileUtils.forceDelete(new File(tmpPath));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 循环填充表格内容
     * @param xwpfDocument
     * @throws Exception
     */
    public static void insertValueToTable(XWPFDocument xwpfDocument, WordDocTableVo wordDocTableVo) throws Exception {
        List<XWPFTable> tableList = xwpfDocument.getTables();
        XWPFTable table = tableList.get(wordDocTableVo.getTableIndex());

        addOrRemoveRow(table,wordDocTableVo.getParams().size(),wordDocTableVo.getRowIndex());

        int row = wordDocTableVo.getRowIndex();
        for (List<String> stringList : wordDocTableVo.getParams()) {
            row++;
            for (int i = 0; i < stringList.size(); i++) {
                table.getRow(row).getCell(i).setText(stringList.get(i));
            }
        }
        table.removeRow(wordDocTableVo.getRowIndex());
    }

    /*
    * @param table 对应表格
    * @param add 增加或删除行数 if add>0 增加行 add<0 删除行
    * @param fromRow 添加开始行位置（fromRow-1是模版行）
    */
    public static void addOrRemoveRow(XWPFTable table, int add,int fromRow) {
        XWPFTableRow row = table.getRow(fromRow-1);
        if(add>0) {
            while(add>0) {
                copyPro(row,table.insertNewTableRow(fromRow));
                add--;
            }
        }else {
            while(add<0) {
                table.removeRow(fromRow-1);
                add++;
            }
        }
    }

    public static void copyPro(XWPFTableRow sourceRow,XWPFTableRow targetRow) {
        //复制行属性
        targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
        List<XWPFTableCell> cellList = sourceRow.getTableCells();
        if(null==cellList) {
            return ;
        }
        //添加列、复制列以及列中段落属性
        XWPFTableCell targetCell = null;
        for(XWPFTableCell sourceCell:cellList) {
            targetCell = targetRow.addNewTableCell();
            //列属性
            targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
            //段落属性
            targetCell.getParagraphs().get(0).getCTP().setPPr(sourceCell.getParagraphs().get(0).getCTP().getPPr());
        }
    }
}