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());
}