最近公司一个项目中需要导出一个简历word版,对于实习生的我开始是无从下手的,后来通过搜索发现可以使用poi来操作。
话不多说,先引入依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
关于word转换pdf需要用到jaboc,所以在这需要先下载jaboc.jar包,链接及提取码如下。后面会用到
链接: https://pan.baidu.com/s/1T7lnY-YdKzwyuH5lDJQyTQ
提取码: 39ar
将jar包解压后,将Jacob.jar包复制到程序的jdk的lib文件夹下,将dll文件复制到jdk的bin目录下
然后在idea中引入jacob.jar包
在这里提供一个单元格方法,因为我是导出简历,所以使用到的表格。当然如果没有表格的话可以看一下我设置的表一和头行
创建表格:两个参数分别是行和列的长度
//创建表格
XWPFTable table = doc.createTable(9+rowLength,7);
该方法用来设置指定表(table),行(i),列(pos)以及设置单元格内容(text);如果是图片的话请往下面看。
/**
* 设置单元格
* @param pos 位置
* @author ty
*/
public static void setCellFont(XWPFTable table,int i,int pos,String text){
//段落
XWPFParagraph para;
XWPFRun run;
XWPFTableRow row;
XWPFTableCell cell;
CTTcPr cellPr;
row = table.getRow(i);
//设置表格高度
row.setHeight(400);
//获取单元格位置,创建单元格
cell = row.getCell(pos);
//单元格属性
cellPr = cell.getCTTc().addNewTcPr();
//设置宽度
cellPr.addNewTcW().setW(BigInteger.valueOf(5000));
//段落
para = cell.getParagraphs().get(0);
//居中对齐方式
para.setAlignment(ParagraphAlignment.CENTER);
//段落对齐方式 1左 2中 3右 4往上 左 不可写0和负数
para.setFontAlignment(2);
run = para.createRun();
//设置字体
run.setFontFamily("宋体");
//这个设置字体大小好像不能用setFontFamily方法,一般使用setFontSize();
run.setFontFamily("五号");
//设置字体加粗
//run.setBold(true);
run.setText(text);
}
设置标题和第一行
//创建word文档
XWPFDocument doc = new XWPFDocument();
XWPFParagraph para1 = doc.createParagraph();
XWPFRun run1 = para1.createRun();
run1.setFontFamily("黑体");
run1.setFontSize(22);
para1.setAlignment(ParagraphAlignment.CENTER);
run1.setText("标题");
XWPFParagraph para2 = doc.createParagraph();
XWPFRun run2 = para2.createRun();
run2.setFontFamily("宋体");
run2.setFontFamily("五号");
para2.setAlignment(ParagraphAlignment.LEFT);
//这里只展示基本内容
run2.setText("内容:"+"时间");
因为表格不确定宽度和高度,有的时候会用到单元格合并,所以在此提供两个合并单元格的方法:
/***
* word跨列合并单元格
* @param table 表
* @param row 行
* @param fromCell 起始列
* @param toCell 结束列
*/
public void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
if ( cellIndex == fromCell ) {
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
} else {
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
}
}
}
/**
* word跨行并单元格
* @param table 表
* @param col 列
* @param fromRow 起始行
* @param toRow 结束行
*/
public void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
if ( rowIndex == fromRow ) {
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
} else {
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
}
}
}
另外对于图片这一块,直接上代码:
//获取图片路径
String imgPath = "图片路径";
row = table.getRow(i);
row.setHeight(400);
cell = row.getCell(j);
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
List<XWPFParagraph> paragraphs = cell.getParagraphs();
XWPFParagraph newPara = paragraphs.get(0);
XWPFRun imageCellRunn = newPara.createRun();
File image = new File(imgPath);
if (!image.exists()) {
continue;
}
try (FileInputStream is = new FileInputStream(imgPath)) {
//判断图片格式,这里只设置了.jpg和.png格式的图片
if(imgPath.substring(imgPath.lastIndexOf(".")+1).equals("jpg")){
imageCellRunn.addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, image.getName(), Units.toEMU(98), Units.toEMU(120));
}else if(imgPath.substring(imgPath.lastIndexOf(".")+1).equals("png")){
imageCellRunn.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, image.getName(), Units.toEMU(98), Units.toEMU(120));
}
} catch (Exception e) {
e.printStackTrace();
}
以上就是基本的word操作了:下面给一个示例,展示一下第六行操作。没有给源码希望大家能够理解
//第六行 教育经历
if(i==5) {
for (int j = 0; j < 7; j++) {
if (j == 0) {
setCellFont(table, i, j, "教育背景(请从高中写起)");
}
if (j == 1) {
setCellBoldFont(table, i, j, "起止时间");
}
if (j == 2) {
setCellBoldFont(table, i, j, "学历");
}
if (j == 3) {
setCellBoldFont(table, i, j, "学校");
}
if (j == 4) {
setCellBoldFont(table, i, j, "专业");
}
if (j == 6) {
setCellBoldFont(table, i, j, "GPA");
}
}
}
下载后,效果如下:(以下简历内容均为编造)
好了,下载完成后重要的一步就是预览了。预览会用到上面所说的jacob.jar包。
提供word转换pdf工具类如下:
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import java.io.File;
/***
* word转换pdf 需要jacob.jar包
*/
public class Word2Pdf {
public static String word2pdf(String path) {
ActiveXComponent app = null;
String pdfFile = null;
//因为word文档有doc和docx格式,所以需要判断
pdfFile = "docx".equals(path.substring(path.lastIndexOf(".")+1))? path.substring(0,path.length()-4)+"pdf" :path.substring(0,path.length()-3)+"pdf";
System.out.println("开始转换...");
// 开始时间
long start = System.currentTimeMillis();
try {
// 打开word
app = new ActiveXComponent("Word.Application");
// 设置word不可见,默认是不可见的,所以可以不写
app.setProperty("Visible", false);
// 获得word中所有打开的文档
Dispatch documents = app.getProperty("Documents").toDispatch();
System.out.println("打开文件: " + path);
// 打开文档
Dispatch document = Dispatch.call(documents, "Open", path, false, true).toDispatch();
// 如果文件存在的话,不会覆盖,会直接报错,所以我们需要判断文件是否存在
File target = new File(pdfFile);
if (target.exists()) {
target.delete();
}
System.out.println("另存为: " + pdfFile);
// 另存为,将文档报错为pdf,其中word保存为pdf的格式宏的值是17
Dispatch.call(document, "SaveAs", pdfFile, 17);
// 关闭文档
Dispatch.call(document, "Close", false);
// 结束时间
long end = System.currentTimeMillis();
System.out.println("转换成功,用时:" + (end - start) + "ms");
}catch(Exception e) {
System.out.println("转换失败"+e.getMessage());
}finally {
// 关闭office
app.invoke("Quit", 0);
}
return pdfFile;
}
}
最终预览效果图如下