Java 导出Word文档

js 请求后端

function exportWord(opId){
	location.href=ctx+'/maintainPro/downloadWord?opId='+opId+"&type=0";
} 

 

java后端代码示例

@RequestMapping(value = "/downloadWord")
	@AdminToolControllerLog(description = "word文档下载")
	public void downloadTemplate(HttpServletRequest req, HttpServletResponse resp,Long opId,String type) throws Exception {
		JsonMsg msg = new JsonMsg();
		MaintainPro maintainPro = maintainproService.findMaintainPro(opId);
		String classpath = this.getClass().getResource("/").getPath();
		String docRoot = classpath.replaceAll("WEB-INF/classes/", "");
		String wordDirUrl = "static/resources/word/";
//		String docRoot = classpath.replaceAll("classes/", "");
//		String wordDirUrl = "RePlan/static/resources/word/";
		String fileName="项目申报书.docx";  //word模板名称		
		String filePath =docRoot+wordDirUrl+fileName;
Map<String, Object> ini = getIniMap(maintainPro); //获取固定字段信息 List<Map<String, Object>> list1 = getTableList(maintainPro,1L); //获取列表数据 List<Map<String, Object>> list2 = getTableList(maintainPro,2L); List<Map<String, Object>> list3 = getTableList(maintainPro,3L); WordReporter wordReporter = new WordReporter(); wordReporter.setTempLocalPath(filePath); wordReporter.init(ini); //固定字段赋值 wordReporter.replaceTableParams(ini, 0); //对应表格固定字段信息赋值 (0指word模板中第一个表格,依次类推) wordReporter.replaceTableParams(ini, 1); wordReporter.replaceTableParams(ini, 2); wordReporter.replaceTableParams(ini, 3); wordReporter.replaceTableParams(ini, 4); wordReporter.replaceTableParams(ini, 5); //遍历(设备、产品软件、应用软件)表格 wordReporter.export(list1,6,1,1); //需要遍历的列表赋值 (6指word模板中第7个表格,表格从第1行开始,以第1行作为创建行) wordReporter.export(list2,7,1,1); wordReporter.export(list3,8,1,1); int index = fileName.indexOf("."); String prefix = fileName.substring(0,index); fileName = fileName.replace(prefix, maintainPro.getPiName()+"申报书"); //导出文件重新命名 buildWordheader(req, resp, fileName); //刷新缓冲 resp.flushBuffer(); OutputStream ouputStream = resp.getOutputStream(); wordReporter.getXwpfDocument().write(ouputStream); if (ouputStream != null) { ouputStream.close(); } msg.setSuccess(true); }

 

//将对象中所需字段转map
public Map<String,Object> getIniMap(MaintainPro maintainPro){ Map<String, Object> map = maintainproService.findIniMapById(maintainPro.getOpId()); if(map!=null) { if(map.get("PI_NAME")!=null) {//项目名称 map.put("piName", map.get("PI_NAME").toString()); } } return map; }

 

public  void buildWordheader(HttpServletRequest req, HttpServletResponse resp,String filename) throws UnsupportedEncodingException {
        resp.reset();
        String fileNameURL = URLEncoder.encode(filename, "UTF-8");
        resp.setCharacterEncoding("UTF-8");
        //response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        resp.setHeader("Content-disposition", "attachment;filename=" + fileNameURL + ";" + "filename*=utf-8''" + fileNameURL);
        resp.setContentType("application/octet-stream");

    }

 

package com.ustc.base.common.util;

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

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;

/**
 * Created by lzx on 2018/8/12
 */

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(Map<String,Object> params) throws IOException{
        inputStream = new FileInputStream(new File(this.tempLocalPath));
        xwpfDocument = new XWPFDocument(inputStream);
        replaceParams(xwpfDocument, params);
    }

    /**
     * 替换段落里面的变量
     *
     * @param doc    要替换的文档
     * @param params 参数
     */
    private static void replaceParams(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph paragraph;
        while (iterator.hasNext()) {
            paragraph = iterator.next();
            replaceParam(paragraph, params);
        }
    }
    
    /**
     * 替换段落里面的变量
     *
     * @param paragraph 要替换的段落
     * @param params    参数
     */
    private static void replaceParam(XWPFParagraph paragraph, Map<String, Object> params) {
        List<XWPFRun> runs;
        Matcher matcher;
        String runText = "";

        if (matcher(paragraph.getParagraphText()).find()) {
            runs = paragraph.getRuns();
            int j = runs.size();
            for (int i = 0; i < j; i++) {
                runText += runs.get(0).toString();
                //保留最后一个段落,在这段落中替换值,保留段落样式
                if (!((j - 1) == i)) {
                    paragraph.removeRun(0);
                }
            }
            matcher = matcher(runText);
            if (matcher.find()) {
                while ((matcher = matcher(runText)).find()) {
                    runText = matcher.replaceFirst(params.get(matcher.group(1))==null?"":params.get(matcher.group(1)).toString());
//                    runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
                }
                runs.get(0).setText(runText, 0);
            }
        }

    }
    
    /**
     * 正则匹配字符串
     *
     * @param str
     * @return
     */
    private static Matcher matcher(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }

    /**
     * @param doc        docx解析对象
     * @param params     需要替换的信息集合
     * @param tableIndex 第几个表格
     * @param tableList  需要插入的表格信息集合
     */
    public static void changeTable(XWPFDocument doc, Map<String, Object> params, int tableIndex, List<String[]> tableList) {
        //获取表格对象集合
        List<XWPFTable> tables = doc.getTables();
        //获取第一个表格   根据实际模板情况 决定去第几个word中的表格
        XWPFTable table = tables.get(tableIndex);
        //替换表格中的参数
       // replaceTableParams(params,0);
        //在表格中插入数据
        insertTable(table, tableList);
    }
    
    /**
     * 为表格插入行数,此处不处理表头,所以从第二行开始
     *
     * @param table     需要插入数据的表格
     * @param tableList 插入数据集合
     */
    private static void insertTable(XWPFTable table, List<String[]> tableList) {
        //创建与数据一致的行数
        for (int i = 0; i < tableList.size(); i++) {
            table.createRow();
        }
        int length = table.getRows().size();
        for (int i = 1; i < length; i++) {
            XWPFTableRow newRow = table.getRow(i);
            List<XWPFTableCell> cells = newRow.getTableCells();
            for (int j = 0; j < cells.size(); j++) {
                XWPFTableCell cell = cells.get(j);
                cell.setText(tableList.get(i - 1)[j]);
            }
        }
    }
    
    /**
     * 替换表格里面的变量
     *
     * @param doc    要替换的文档
     * @param params 参数
     */
    public void replaceTableParams( Map<String, Object> params,int tableIndex) {
        
        List<XWPFTable> tableList = xwpfDocument.getTables();
        XWPFTable table =tableList.get(tableIndex);;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;
            //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
            if (matcher(table.getText()).find()) {
                rows = table.getRows();
                for (XWPFTableRow row : rows) {
                    cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        paras = cell.getParagraphs();
                        for (XWPFParagraph para : paras) {
                            replaceParam(para, params);
                        }
                    }
                }
            }
    }
   
    
    
   /**
    * 导出方法
    * @param params
    * @param tableIndex word的表格索引
    * @param rownum   从第几行开始
    * @param createrowindex 以第几行作为创建行
    * @return
    * @throws Exception
    */
    public boolean export(List<Map<String,Object>> params, int tableIndex,int rownum,int createrowindex) throws Exception{
        this.insertValueToTable(xwpfDocument,params,tableIndex,rownum,createrowindex);
        return true;
    }

    /**
     * 循环填充表格内容
     * @param xwpfDocument
     * @param params
     * @param tableIndex
     * @throws Exception
     */
    private void insertValueToTable(XWPFDocument xwpfDocument, List<Map<String,Object>> params, int tableIndex,int rownum,int createrowindex) 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行");
        }
        //模板的那一行
        XWPFTableRow tmpRow = rows.get(rownum);
        List<XWPFTableCell> tmpCells = null;
        List<XWPFTableCell> cells = null;
        XWPFTableCell tmpCell = null;
        tmpCells = tmpRow.getTableCells();
        table.getCTTbl();
       
        String cellText = null;
        String cellTextKey = null;
        Map<String,Object> totalMap = null;
        for (int i = 0, len = params.size(); i < len; i++) {
            Map<String,Object> map = params.get(i);
            // 创建新的一行
          //  XWPFTableRow row = table.createRow();
            XWPFTableRow row = createRow(table.getCTTbl(),table,createrowindex);
            // 获取模板的行高 设置为新一行的行高
            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("}", "").replaceAll("[^a-zA-Z0-9_\\u4E00-\\u9FA5]", "");
                    if (map.containsKey(cellTextKey)) {
                        // 填充内容 并且复制模板行的属性
                        setCellText(tmpCell,cell,map.get(cellTextKey)==null?"":map.get(cellTextKey).toString());
                    }
                }
            }

        }
        // 删除模版行
        table.removeRow(rownum);
    }
    
    private XWPFTableRow createRow(CTTbl ctTbl,XWPFTable table,int i){
          int sizeCol = ctTbl.sizeOfTrArray() > 0 ? ctTbl.getTrArray(i)
                  .sizeOfTcArray() : 0;
          XWPFTableRow tabRow = new XWPFTableRow(ctTbl.addNewTr(), table);
          addColumn(tabRow, sizeCol);
          //tableRows.add(tabRow);
          return tabRow;
    }
    
    private void addColumn(XWPFTableRow tabRow, int sizeCol) {
        if (sizeCol > 0) {
            for (int i = 0; i < sizeCol; i++) {
                tabRow.createCell();
            }
        }
    }

    /**
     *  复制模板行的属性
     * @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());
                    }
                }
            }
        }
    }

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

    /**
     *  关闭输入流
     * @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();
            }
        }
    }

    public XWPFDocument getXwpfDocument() {
        return xwpfDocument;
    }

    public OutputStream getOutputStream() {
        return outputStream;
    }

}

 word模板示例:

 

 

 

 

 

 

 

 

 

 

posted on 2021-07-19 16:50  ALWAYS☆REMIND  阅读(493)  评论(0编辑  收藏  举报

导航