1 需求
在列表页面中点击合同按钮,跳转到合同页面
 
 页面中有下载按钮,点击下载按钮,把页面展示的内容导出到word中。
 
2 分析
2.1 POI操作Word的API介绍
poi对低版本的doc本身支持的就不好所以我们直接说高版本的docx版本的api。
1、poi操作word正文
XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档
一个文档包含多个段落,一个段落包含多个Runs文本,一个Runs包含多个Run,Run是文档的最小单元
获取所有段落:List<XWPFParagraph> paragraphs = word.getParagraphs();
获取一个段落中的所有片段Runs:List<XWPFRun> xwpfRuns = xwpfParagraph.getRuns();
获取一个Runs中的一个Run:XWPFRun run = xwpfRuns.get(index);
2、poi操作word中的表格
一个文档包含多个表格,一个表格包含多行,一行包含多列单元格
获取所有表格:List<XWPFTable> xwpfTables = doc.getTables();
获取一个表格中的所有行:List<XWPFTableRow> xwpfTableRows = xwpfTable.getRows();
获取一行中的所有列:List<XWPFTableCell> xwpfTableCells = xwpfTableRow.getTableCells();
获取一格里的内容:List<XWPFParagraph> paragraphs = xwpfTableCell.getParagraphs();
之后和正文段落一样
2.2 思路分析
首先我们先制作一个word模板,把动态的内容先写特殊字符然后替换,表格的话需要我们自己创建然后向表格中放内容。
 
3 代码实现
第一步:制作模板(模板内容如上图所示),放入到项目中
 
第二步:提供根据id查询用户的方法,并且用户中带有办公资源数据
1、User类中添加一个集合属性
 
2、UserController代码
提供一个根据用户ID查询用户对象
@GetMapping("/{id}")
public User  findById(@PathVariable("id") Long id){
    return userService.findById(id);
}
3、UserService代码
查询用户信息,并且查询用户的办公用品数据,赋值到用户中
@Autowired
private ResourceMapper resourceMapper;
public User findById(Long id) {
    //查询用户
    User user = userMapper.selectByPrimaryKey(id);
    //根据用户id查询办公用品
    Resource resource = new Resource();
    resource.setUserId(id);
    List<Resource> resourceList = resourceMapper.select(resource);
    user.setResourceList(resourceList);
    return user;
}
第三步:完成导出word功能
Controller代码
@GetMapping(value = "/downloadContract",name = "导出用户合同")
public void downloadContract(Long id,HttpServletResponse response) throws Exception{
    userService.downloadContract(id,response);
}
UserService代码
先准备两个方法,一个是想指定的单元格中放入图片,另一个是 复制word中表格的行
//    向单元格中写入图片
private void setCellImage(XWPFTableCell cell, File imageFile) {
    XWPFRun run = cell.getParagraphs().get(0).createRun();
    //        InputStream pictureData, int pictureType, String filename, int width, int height
    try(FileInputStream inputStream = new FileInputStream(imageFile)) {
        run.addPicture(inputStream,XWPFDocument.PICTURE_TYPE_JPEG,imageFile.getName(), Units.toEMU(100),Units.toEMU(50));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
//    用于深克隆行
private void copyRow(XWPFTable xwpfTable, XWPFTableRow sourceRow, int rowIndex) {
    XWPFTableRow targetRow = xwpfTable.insertNewTableRow(rowIndex);
    targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
    //        获取源行的单元格
    List<XWPFTableCell> cells = sourceRow.getTableCells();
    if(CollectionUtils.isEmpty(cells)){
        return;
    }
    XWPFTableCell targetCell = null;
    for (XWPFTableCell cell : cells) {
        targetCell = targetRow.addNewTableCell();
        //            附上单元格的样式
        //            单元格的属性
        targetCell.getCTTc().setTcPr(cell.getCTTc().getTcPr());
        targetCell.getParagraphs().get(0).getCTP().setPPr(cell.getParagraphs().get(0).getCTP().getPPr());
    }
}
完成导出主体方法
/**
     * 下载用户合同数据
     * @param id
     */
public void downloadContract(Long id,HttpServletResponse response) throws Exception {
    //        1、读取到模板
    File rootFile = new File(ResourceUtils.getURL("classpath:").getPath()); //获取项目的根目录
    File templateFile = new File(rootFile, "/word_template/contract_template.docx");
    XWPFDocument word = new XWPFDocument(new FileInputStream(templateFile));
    //        2、查询当前用户User--->map
    User user = this.findById(id);
    Map<String,String> params = new HashMap<>();
    params.put("userName",user.getUserName());
    params.put("hireDate",simpleDateFormat.format(user.getHireDate()));
    params.put("address",user.getAddress());
    //        3、替换数据
    //         处理正文开始
    List<XWPFParagraph> paragraphs = word.getParagraphs();
    for (XWPFParagraph paragraph : paragraphs) {
        List<XWPFRun> runs = paragraph.getRuns();
        for (XWPFRun run : runs) {
            String text = run.getText(0);
            for (String key : params.keySet()) {
                if(text.contains(key)){
                    run.setText(text.replaceAll(key,params.get(key)),0);
                }
            }
        }
    }
    //         处理正文结束
    //      处理表格开始     名称	价值	是否需要归还	照片
    List<Resource> resourceList = user.getResourceList(); //表格中需要的数据
    XWPFTable xwpfTable = word.getTables().get(0);
    XWPFTableRow row = xwpfTable.getRow(0);
    int rowIndex = 1;
    for (Resource resource : resourceList) {
        //        添加行
        //            xwpfTable.addRow(row);
        copyRow(xwpfTable,row,rowIndex);
        XWPFTableRow row1 = xwpfTable.getRow(rowIndex);
        row1.getCell(0).setText(resource.getName());
        row1.getCell(1).setText(resource.getPrice().toString());
        row1.getCell(2).setText(resource.getNeedReturn()?"需求":"不需要");
        File imageFile = new File(rootFile,"/static"+resource.getPhoto());
        setCellImage(row1.getCell(3),imageFile);
        rowIndex++;
    }
    //     处理表格开始结束
    //        4、导出word
    String filename = "员工(" + user.getUserName() + ")合同.docx";
    response.setHeader("content-disposition", "attachment;filename=" + new String(filename.getBytes(), "ISO8859-1"));
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    word.write(response.getOutputStream());
}



















