Secuencia de archivo Java en segundo plano, secuencia de archivo de lectura vue en la palabra de descarga en primer plano

Idea general, organízala cuando estés libre

Este método consiste en tener primero la plantilla de Word y luego reemplazar el contenido en la plantilla. El contenido de la plantilla se divide en 2 bloques, uno está en el párrafo y el otro es el formulario que debe generarse dinámicamente, por lo que hay también dos métodos de fondo

1: Método en segundo plano (este método está organizado para Baidu)

Clase pública de WordReporter:

package com.fencer.common.wordUtil;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WordReporter {

    private String tempLocalPath;
    private XWPFDocument xwpfDocument = null;
    private FileInputStream inputStream = null;
    private OutputStream outputStream = null;

    public WordReporter(){

    }
    public WordReporter(String tempLocalPath){
        this.tempLocalPath = tempLocalPath;
    }

    /**
     *  设置模板路径
     * @param tempLocalPath
     */
    public void setTempLocalPath(String tempLocalPath) {
        this.tempLocalPath = tempLocalPath;
    }

    /**
     *  初始化
     * @throws IOException
     */
    public void init() throws IOException{
        inputStream = new FileInputStream(new File(this.tempLocalPath));
        xwpfDocument = new XWPFDocument(inputStream);
    }

    /**
     *  导出方法
     * @param
     * @param tableIndex
     * @return
     * @throws Exception
     */
    public boolean export( Map<String,Object> map, int tableIndex) throws Exception{
        this.insertValueToTable(xwpfDocument,map,tableIndex);
        return true;
    }

    /**
     * 循环填充表格内容
     * @param xwpfDocument
     * @param
     * @param tableIndex
     * @throws Exception
     */
    private   void insertValueToTable(XWPFDocument xwpfDocument, Map<String,Object> mapAll, int tableIndex) throws Exception {
        List<XWPFTable> tableList = xwpfDocument.getTables();
        if(tableList.size()<=tableIndex){
            throw new Exception("tableIndex对应的表格不存在");
        }
        XWPFTable table = tableList.get(tableIndex);
        List<XWPFTableRow> rows = table.getRows();
        if(rows.size()<2){
            throw new Exception("tableIndex对应表格应该为2行");
        }
        //替换段落里面的变量
        this.replaceInPara(xwpfDocument, mapAll);

        List<Map<String,String>> params = (List<Map<String, String>>) mapAll.get("list");


        //模板的那一行
        XWPFTableRow tmpRow = rows.get(1);
        List<XWPFTableCell> tmpCells = null;
        List<XWPFTableCell> cells = null;
        XWPFTableCell tmpCell = null;
        tmpCells = tmpRow.getTableCells();


        String cellText = null;
        String cellTextKey = null;
        Map<String,Object> totalMap = null;
        for (int i = 0, len = params.size(); i < len; i++) {
            Map<String,String> map = params.get(i);
            // 创建新的一行
            XWPFTableRow row = table.createRow();
            // 获取模板的行高 设置为新一行的行高
            row.setHeight(tmpRow.getHeight());
            cells = row.getTableCells();
            for (int k = 0, klen = cells.size(); k < klen; k++) {
                tmpCell = tmpCells.get(k);
                XWPFTableCell cell = cells.get(k);
                cellText = tmpCell.getText();
                if (StringUtils.isNotBlank(cellText)) {
                    //转换为mapkey对应的字段
                    cellTextKey = cellText.replace("$", "").replace("{", "").replace("}", "");
                    if (map.containsKey(cellTextKey)) {
                        // 填充内容 并且复制模板行的属性
                        setCellText(tmpCell,cell,map.get(cellTextKey));
                    }
                }
            }

        }
        // 删除模版行
        table.removeRow(1);
    }

    /**
     *  复制模板行的属性
     * @param tmpCell
     * @param cell
     * @param text
     * @throws Exception
     */
    private void setCellText(XWPFTableCell tmpCell, XWPFTableCell cell,String text) throws Exception {

        CTTc cttc2 = tmpCell.getCTTc();
        CTTcPr ctPr2 = cttc2.getTcPr();
        CTTc cttc = cell.getCTTc();
        CTTcPr ctPr = cttc.addNewTcPr();
        if (ctPr2.getTcW() != null) {
            ctPr.addNewTcW().setW(ctPr2.getTcW().getW());
        }
        if (ctPr2.getVAlign() != null) {
            ctPr.addNewVAlign().setVal(ctPr2.getVAlign().getVal());
        }
        if (cttc2.getPList().size() > 0) {
            CTP ctp = cttc2.getPList().get(0);
            if (ctp.getPPr() != null) {
                if (ctp.getPPr().getJc() != null) {
                    cttc.getPList().get(0).addNewPPr().addNewJc()
                            .setVal(ctp.getPPr().getJc().getVal());
                }
            }
        }
        if (ctPr2.getTcBorders() != null) {
            ctPr.setTcBorders(ctPr2.getTcBorders());
        }

        XWPFParagraph tmpP = tmpCell.getParagraphs().get(0);
        XWPFParagraph cellP = cell.getParagraphs().get(0);
        XWPFRun tmpR = null;
        if (tmpP.getRuns() != null && tmpP.getRuns().size() > 0) {
            tmpR = tmpP.getRuns().get(0);
        }
        XWPFRun cellR = cellP.createRun();
        cellR.setText(text);
        // 复制字体信息
        if (tmpR != null) {
            if(!cellR.isBold()){
                cellR.setBold(tmpR.isBold());
            }
            cellR.setItalic(tmpR.isItalic());
            cellR.setUnderline(tmpR.getUnderline());
            cellR.setColor(tmpR.getColor());
            cellR.setTextPosition(tmpR.getTextPosition());
            if (tmpR.getFontSize() != -1) {
                cellR.setFontSize(tmpR.getFontSize());
            }
            if (tmpR.getFontFamily() != null) {
                cellR.setFontFamily(tmpR.getFontFamily());
            }
            if (tmpR.getCTR() != null) {
                if (tmpR.getCTR().isSetRPr()) {
                    CTRPr tmpRPr = tmpR.getCTR().getRPr();
                    if (tmpRPr.isSetRFonts()) {
                        CTFonts tmpFonts = tmpRPr.getRFonts();
                        CTRPr cellRPr = cellR.getCTR().isSetRPr() ? cellR
                                .getCTR().getRPr() : cellR.getCTR().addNewRPr();
                        CTFonts cellFonts = cellRPr.isSetRFonts() ? cellRPr
                                .getRFonts() : cellRPr.addNewRFonts();
                        cellFonts.setAscii(tmpFonts.getAscii());
                        cellFonts.setAsciiTheme(tmpFonts.getAsciiTheme());
                        cellFonts.setCs(tmpFonts.getCs());
                        cellFonts.setCstheme(tmpFonts.getCstheme());
                        cellFonts.setEastAsia(tmpFonts.getEastAsia());
                        cellFonts.setEastAsiaTheme(tmpFonts.getEastAsiaTheme());
                        cellFonts.setHAnsi(tmpFonts.getHAnsi());
                        cellFonts.setHAnsiTheme(tmpFonts.getHAnsiTheme());
                    }
                }
            }

        }
        // 复制段落信息
        cellP.setAlignment(tmpP.getAlignment());
        cellP.setVerticalAlignment(tmpP.getVerticalAlignment());
        cellP.setBorderBetween(tmpP.getBorderBetween());
        cellP.setBorderBottom(tmpP.getBorderBottom());
        cellP.setBorderLeft(tmpP.getBorderLeft());
        cellP.setBorderRight(tmpP.getBorderRight());
        cellP.setBorderTop(tmpP.getBorderTop());
        cellP.setPageBreak(tmpP.isPageBreak());
        if (tmpP.getCTP() != null) {
            if (tmpP.getCTP().getPPr() != null) {
                CTPPr tmpPPr = tmpP.getCTP().getPPr();
                CTPPr cellPPr = cellP.getCTP().getPPr() != null ? cellP
                        .getCTP().getPPr() : cellP.getCTP().addNewPPr();
                // 复制段落间距信息
                CTSpacing tmpSpacing = tmpPPr.getSpacing();
                if (tmpSpacing != null) {
                    CTSpacing cellSpacing = cellPPr.getSpacing() != null ? cellPPr
                            .getSpacing() : cellPPr.addNewSpacing();
                    if (tmpSpacing.getAfter() != null) {
                        cellSpacing.setAfter(tmpSpacing.getAfter());
                    }
                    if (tmpSpacing.getAfterAutospacing() != null) {
                        cellSpacing.setAfterAutospacing(tmpSpacing
                                .getAfterAutospacing());
                    }
                    if (tmpSpacing.getAfterLines() != null) {
                        cellSpacing.setAfterLines(tmpSpacing.getAfterLines());
                    }
                    if (tmpSpacing.getBefore() != null) {
                        cellSpacing.setBefore(tmpSpacing.getBefore());
                    }
                    if (tmpSpacing.getBeforeAutospacing() != null) {
                        cellSpacing.setBeforeAutospacing(tmpSpacing
                                .getBeforeAutospacing());
                    }
                    if (tmpSpacing.getBeforeLines() != null) {
                        cellSpacing.setBeforeLines(tmpSpacing.getBeforeLines());
                    }
                    if (tmpSpacing.getLine() != null) {
                        cellSpacing.setLine(tmpSpacing.getLine());
                    }
                    if (tmpSpacing.getLineRule() != null) {
                        cellSpacing.setLineRule(tmpSpacing.getLineRule());
                    }
                }
                // 复制段落缩进信息
                CTInd tmpInd = tmpPPr.getInd();
                if (tmpInd != null) {
                    CTInd cellInd = cellPPr.getInd() != null ? cellPPr.getInd()
                            : cellPPr.addNewInd();
                    if (tmpInd.getFirstLine() != null) {
                        cellInd.setFirstLine(tmpInd.getFirstLine());
                    }
                    if (tmpInd.getFirstLineChars() != null) {
                        cellInd.setFirstLineChars(tmpInd.getFirstLineChars());
                    }
                    if (tmpInd.getHanging() != null) {
                        cellInd.setHanging(tmpInd.getHanging());
                    }
                    if (tmpInd.getHangingChars() != null) {
                        cellInd.setHangingChars(tmpInd.getHangingChars());
                    }
                    if (tmpInd.getLeft() != null) {
                        cellInd.setLeft(tmpInd.getLeft());
                    }
                    if (tmpInd.getLeftChars() != null) {
                        cellInd.setLeftChars(tmpInd.getLeftChars());
                    }
                    if (tmpInd.getRight() != null) {
                        cellInd.setRight(tmpInd.getRight());
                    }
                    if (tmpInd.getRightChars() != null) {
                        cellInd.setRightChars(tmpInd.getRightChars());
                    }
                }
            }
        }
    }

    /**
     * @方法描述: 替换段落里面的变量
     * doc 要替换的文档  params 替换的参数,数据库查询出来的数据
     * @return: void
     * @Author: carry
     */
    private void replaceInPara(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph para;
        while (iterator.hasNext()) {
            para = iterator.next();
            this.replaceInPara(para, params);
        }
    }
    /**
     * @方法描述: 替换段落里面的变量
     * para 要替换的文档  params 替换的参数,数据库查询出来的数据
     * @return: void
     * @Author: carry
     */
    private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
        List<XWPFRun> runs;
        Matcher matcher;
        if (this.matcher(para.getParagraphText()).find()) {
            runs = para.getRuns();
            for (int i = 0; i < runs.size(); i++) {
                XWPFRun run = runs.get(i);
                String runText = run.toString();
                matcher = this.matcher(runText);
                if (matcher.find()) {
                    while ((matcher = this.matcher(runText)).find()) {
                        runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
                    }
                    //直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,
                    //所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。
                    para.removeRun(i);
                    para.insertNewRun(i).setText(runText);
                }
            }
        }
    }

    /**
     * @方法描述:  正则匹配字符串
     * @return: java.util.regex.Matcher
     * @Author: carry
     */
    private Matcher matcher(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }

    /**
     *  收尾方法
     * @param outDocPath
     * @return
     * @throws IOException
     */
    public boolean generate(String outDocPath) throws IOException{
        outputStream = new FileOutputStream(outDocPath);
        xwpfDocument.write(outputStream);
        return true;
    }

    /**
     * @方法描述:
     * path 下载的文件路径  projectname  这里意义不大 直接被vue前台替换了   suffix后缀名  这里意义不大 直接被vue前台替换了
     * @return: javax.servlet.http.HttpServletResponse
     * @Author: carry
     */
    public HttpServletResponse download(String downloadPath, HttpServletResponse response) throws Exception {
        // path是指欲下载的文件的路径。
        File file = new File(downloadPath);
        // 以流的形式下载文件。
        InputStream fis = new BufferedInputStream(new FileInputStream(downloadPath));
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();
        response.reset();
        // 设置response的Header  这里意义不大 直接被vue前台替换了 所以可以删掉
        response.addHeader("Content-Disposition", "attachment;filename="
                + new String(("" + "docx").getBytes("gbk"),
                "iso-8859-1"));
        response.addHeader("Content-Length", "" + file.length());
        OutputStream toClient = new BufferedOutputStream(
                response.getOutputStream());
        //注意这里很重要 vue的回调里根据ContentType类判断是否是下载的操作,这里不要改
        response.setContentType("application/octet-stream");
        toClient.write(buffer);
        toClient.flush();
        this.close(fis);
        this.close(toClient);
        return response;
    }

    /**
     *  关闭输入流
     * @param is
     */
    private void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *  关闭输出流
     * @param os
     */
    private void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

 

Método de llamada

 @Test
    public void test() throws Exception {
        //数据库的字段名,需要与上传模板的变量对应
        Map<String ,Object> resultMap=new HashMap<String ,Object>();
        SimpleDateFormat sdfYear =new SimpleDateFormat("yyyy年MM月dd日");
        SimpleDateFormat sdfMine =new SimpleDateFormat("yyyy年MM月dd日 HH时");
        Date date=new Date();
        String reportDate=sdfYear.format(date);
        String reportTime=sdfMine.format(date);
       //后期可以改为动态的适应word模板
        resultMap.put("yearid","2018-2019");
        resultMap.put("period","1");
        resultMap.put("reportDate",reportDate);
        resultMap.put("reportTime",reportTime);
        resultMap.put("ysll","39.98");
        resultMap.put("nsbtrc","30.8");
        resultMap.put("dyzrc","9.18");

        resultMap.put("szbz","28.4");
        resultMap.put("wrbz","26.1");
        resultMap.put("sz","11.3");
        resultMap.put("qd","14.48");
        resultMap.put("qdrps","118.45");
        resultMap.put("jhtrk","105.49");
        resultMap.put("jhtck","92");
        resultMap.put("jhtsw","13.57");
        resultMap.put("wfrps","60.03");
        resultMap.put("ytrps","48.07");
        resultMap.put("whrps","41.96");


        // 添加假数据 这里你也可以从数据库里获取数据
        List<Map<String, String>> list = new ArrayList<>();
        for (int i =0;i < 10; i++){
            Map<String,String> map = new HashMap<>();
            map.put("stnm", "分水口"+i);
            map.put("q",  "20");
            map.put("w", "30");
            map.put("total_w", "50");
            list.add(map);
        }
        resultMap.put("list",list);
        // 模板文件输入输出地址
        String filePath = "C:\\Users\\叶子\\Desktop\\reportTemplate.docx";
        String outPath = "C:\\Users\\叶子\\Desktop\\reportTemplateReal.docx";
        WordReporter wordReporter = new WordReporter();
        wordReporter.setTempLocalPath(filePath);
        wordReporter.init();
        wordReporter.export(resultMap,0);
        wordReporter.generate(outPath);

    }

 

Encapsulé el método http en vue en la recepción: http.js

  //导出文件
    export(config) {
        if (config.data) {
            config.responseType="blob";
            config.params = {...config.params, ...config.data};
            if(config.data.params != undefined){
                config.params={ ...config.params,...config.data.params}
            }

            delete config.data;
        }
        return this.request(config);
    }

 

Página específica llamada:

<el-button type = "text" size = "small" @ click = "exportWord (scope.row)"> 下载 </el-button>

//导出word
    exportsWord(row) {
      let params = {};
      //传参id或者直接传参文件路径也可以到后台
      params.id = row.id;
      let fileName =
        row.deptname +
        row.yearid +
        "年度" +
        row.tm +
        "日第" +
        row.period +
        "期运行日报";
      this.$api.exportToWord(params).then(res => {
        if (res.code == "0") {
          let data = res.result.data;
          console.log(data);
          let blob = new Blob([data], {
            //type   mimi类型  可以百度详细类型
            //word文档为msword,application/pdfpdf文档为pdf  application/vnd.ms-excel
            //image/jpeg jpg
            type: `application/msword`
          });
          let objectUrl = URL.createObjectURL(blob);
          let link = document.createElement("a");
          let fname = fileName;
          link.href = objectUrl;
          link.setAttribute("download", fname);
          document.body.appendChild(link);
          link.click();
        } else {
          this.$message.error(res.msg);
        }
      });
    },

 

Supongo que te gusta

Origin blog.csdn.net/CarryBest/article/details/94630824
Recomendado
Clasificación