导入相关javadoc和opi的jar包
<!--javadoc读取需导入jar包-->
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-core -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.4.M1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--javaopi相关坐标-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.0.1</version>
</dependency>
创建javadoc读取类三个类
public class Doclet {
public static Logger logger = LoggerFactory.getLogger(Doclet.class);
private static RootDoc rootDoc;
private String javaBeanFilePath;
public static boolean start(RootDoc root) {
rootDoc = root;
return true;
}
public Doclet(String javaBeanFilePath) {
this.javaBeanFilePath = javaBeanFilePath;
}
public ModelClassDocVO exec() {
ModelClassDocVO modelClassDocVO = new ModelClassDocVO();
com.sun.tools.javadoc.Main.execute(new String[]{"-doclet", Doclet.class.getName(), "-docletpath",
Doclet.class.getResource("/").getPath(), "-encoding", "utf-8", javaBeanFilePath});
ClassDoc[] classes = rootDoc.classes();
if (classes == null || classes.length == 0) {
logger.warn(javaBeanFilePath + " 无ClassDoc信息");
return modelClassDocVO;
}
List<FildEntry> entrys = Lists.newArrayList();
ClassDoc classDoc = classes[0];
// 获取类的名称
modelClassDocVO.setModelClassName(classDoc.name());
// 获取类的注释
String classComment = ReflectUtil.getFieldValue(classDoc, "documentation").toString();
String spitStr = "\n";
for (String msg : classComment.split(spitStr)) {
if (!msg.trim().startsWith("@") && msg.trim().length() > 0) {
modelClassDocVO.setModelCommentText(msg);
break;
}
}
// 获取属性名称和注释
FieldDoc[] fields = classDoc.fields(false);
for (FieldDoc field : fields) {
entrys.add(new FildEntry(field.name(), field.type().typeName(), field.commentText()));
}
modelClassDocVO.setFildEntryList(entrys);
return modelClassDocVO;
}
}
public class FildEntry {
/**
* 参数名
*/
private String fName;
/**
* 类型
*/
private String fType;
/**
* 说明
*/
private String fExplain;
public FildEntry(String fName, String fType, String fExplain) {
super();
this.fName = fName;
this.fType = fType;
this.fExplain = fExplain;
}
@Override
public String toString() {
return "Entry{" +
"fName='" + fName + '\'' +
", fType='" + fType + '\'' +
", fExplain='" + fExplain + '\'' +
'}';
}
public String getfName() {
return fName;
}
public void setfName(String fName) {
this.fName = fName;
}
public String getfType() {
return fType;
}
public void setfType(String fType) {
this.fType = fType;
}
public String getfExplain() {
return fExplain;
}
public void setfExplain(String fExplain) {
this.fExplain = fExplain;
}
}
public class ModelClassDocVO {
private String modelTableName;
private String modelClassName;
private String modelCommentText;
private List<FildEntry> fildEntryList;
public String getModelTableName() {
return modelTableName;
}
public void setModelTableName(String modelTableName) {
this.modelTableName = modelTableName;
}
public String getModelClassName() {
return modelClassName;
}
public void setModelClassName(String modelClassName) {
this.modelClassName = modelClassName;
}
public String getModelCommentText() {
return modelCommentText;
}
public void setModelCommentText(String modelCommentText) {
this.modelCommentText = modelCommentText;
}
public List<FildEntry> getFildEntryList() {
return fildEntryList;
}
public void setFildEntryList(List<FildEntry> fildEntryList) {
this.fildEntryList = fildEntryList;
}
@Override
public String toString() {
return "ModelClassDocVO{" +
"modelClassName='" + modelClassName + '\'' +
", modelCommentText='" + modelCommentText + '\'' +
", fildEntryList=" + fildEntryList +
'}';
}
}
使用opi创建报表
public class ExportDataUtils {
/**
* url传入全路径名,获取doc文档内容,生成模板
*
* @param url
* @param <T>
* @return
* @throws IOException
*/
public static <T> Map<XSSFWorkbook,XSSFSheet> excelTemplate(String url) throws IOException {
Doclet doclet = new Doclet(url);
ModelClassDocVO exec = doclet.exec();
ArrayList<String> headerDocument = new ArrayList<>();
//获取文档名称
for (FildEntry fildEntry : exec.getFildEntryList()) {
headerDocument.add(fildEntry.getfExplain());
}
XSSFWorkbook xb = new XSSFWorkbook();
XSSFSheet sheet = xb.createSheet(UUID.randomUUID().toString());
//设置单元格样式
CellStyle cellStyle = xb.createCellStyle();
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
//根据数据内容合并单元格
sheet.addMergedRegion(new CellRangeAddress(1, 1, 1, headerDocument.size()));
//居中单元格
//写入单元格副标题
XSSFRow row_1 = sheet.createRow(1);
int cell_1_1 = 1;
for (int i = 0; i < headerDocument.size(); i++) {
//设置标题信息
XSSFCell cell = row_1.createCell(cell_1_1);
cell.setCellStyle(cellStyle);
cell.setCellValue(exec.getModelCommentText());
cell_1_1++;
}
int cell_2_1 = 1;
XSSFRow row_2 = sheet.createRow(2);
for (String headerName : headerDocument) {
XSSFCell cell = row_2.createCell(cell_2_1);
cell.setCellStyle(cellStyle);
cell.setCellValue(headerName);
cell_2_1++;
}
Map<XSSFWorkbook,XSSFSheet> map = new HashMap<>();
map.put(xb,sheet);
return map;
}
}
测试类
/**
* 患者信息表
*/
public class Patient_information implements Serializable {
/**
* id
*/
private String id;
/**
* 真实姓名
*/
private String patientName;
/**
* 网站昵称
*/
private String webName;
/**
* 联系电话
*/
private String patientPhone;
/**
* 电子邮件
*/
private String patientEmail;
/**
* 身份证号码
*/
private String identityNumber;
/**
* 密码
*/
private String password;
/**
* 头像路径
*/
private String avatarUrl;
/**
* 性别
*/
private int patientSex;
/**
* 生日日期
*/
private Date patientBirth;
/**
* 家庭住址
*/
private String patientAddr;
/**
* 年龄
*/
private int patientAge;
}
页面接收测试
@PostMapping("/dataTemplateDownload")
public void patientTemplateDownload(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
String fileName=new String((UUID.randomUUID().toString() + ".xlsx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
//设置文件名
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.addHeader("Content-Disposition", "attachment;fileName="+fileName);
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
//获取产生相应的流对象
String url=System.getProperty("user.dir")+"\\src\\main\\java\\pojo\\patient\\Patient_information.java";
ByteArrayOutputStream os = patientService.patientTemplateDownload(url);
ServletOutputStream outputStream = response.getOutputStream();
//将数据从原始字节流对象提取出来写入到servlet对应的输出流中
os.writeTo(outputStream);
outputStream.flush();
outputStream.close();
}
测试结果
此时我们可以看到数据已经导出