package com.admin.common.utils.poi;

import cn.afterturn.easypoi.word.WordExportUtil;
import cn.afterturn.easypoi.word.entity.MyXWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class WordUtil {
    /**
     * 导出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, Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) {
        Assert.notNull(templatePath,"模板路径不能为空");
        Assert.notNull(temDir,"临时路径不能为空");
        Assert.notNull(fileName,"表名不能为空");
        Assert.isTrue(fileName.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")) {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else {
                fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
            }

            //根据模板和数据生成文档
            InputStream resourceAsStream = WordUtil.class.getClassLoader().getResourceAsStream(templatePath);
            Assert.notNull(resourceAsStream,"模板文件不存在");
            XWPFDocument doc = new MyXWPFDocument(resourceAsStream);
            WordExportUtil.exportWord07(doc, params);

            String tmpPath = temDir + fileName;
            FileOutputStream fos = new FileOutputStream(tmpPath);
            doc.write(fos);
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            // 设置文件名
            response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
            OutputStream out = response.getOutputStream();
            doc.write(out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            delFileWord(temDir,fileName);//删除暂存
        }
    }
    /**
     * 删除临时生成的文件
     */
    public static void delFileWord(String filePath, String fileName){
        File file =new File(filePath+fileName);
        File file1 =new File(filePath);
        file.delete();
        file1.delete();
    }

    /**
     * 压缩输出
     * @param list word文档列表
     * @param listName 学生名称列表
     * @param response
     * @throws IOException
     */
    public static void exportZip(List<XWPFDocument> list, List<String> listName, HttpServletResponse response) throws IOException {
        ZipOutputStream zos = null;
        ByteArrayOutputStream arrayOutputStream = null;
        try {
            response.reset();
            // 指明response的返回对象是文件流
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" +new String("志愿表".getBytes("GB2312"),"iso-8859-1")+".zip");
            zos = new ZipOutputStream(response.getOutputStream());//压缩文件输出流
            arrayOutputStream= new ByteArrayOutputStream();//ByteArray临时存储流
            //查询要导出的列表
            for (int i =0; i<list.size(); i++) {
                try {
                    //放入zipEntry实体，取一个名字
                    zos.putNextEntry(new ZipEntry(listName.get(i) + "_分流志愿表.docx"));
                    //重置ByteArray流（为了重复使用）
                    arrayOutputStream.reset();
                    //把word对象内容写到ByteArray流临时存储
                    list.get(i).write(arrayOutputStream);
                    //把ByteArray流内容写入zip输出流
                    zos.write(arrayOutputStream.toByteArray());
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null != zos){
                zos.closeEntry();
                zos.flush();
                zos.close();
            }
            if(arrayOutputStream!=null) {
                arrayOutputStream.close();
            }
        }
    }
}
