java代码实现导出或者下载xml、word、pdf、exc

java代码实现导出或者下载xml、word、pdf、excel功能

写在前面:将用户操作日志以xml、word、pdf、excel格式的文件导出。

1、导出xml

导出xml使用JAXB的注解实现,实体如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
typescript复制代码import javax.xml.bind.annotation.*;
import java.util.List;

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "", propOrder = {
"title",
"log"
})
@XmlRootElement(name = "Body")
public class Submit {

private String title;

protected List<LogX> logX;

@XmlElementWrapper(name = "logList")
public List<LogX> getLog() {
return logX;
}

public void setLog(List<LogX> logX) {
this.logX = logX;
}

@XmlElement(name = "title", required = true,nillable=true)
public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}
}

LogX实体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
typescript复制代码import javax.xml.bind.annotation.*;
import java.io.Serializable;


@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "", propOrder = {
"username",
"operationIp",
"createTime",
"operation",
"content"
})
@XmlRootElement(name = "log")
public class LogX implements Serializable {

private static final long serialVersionUID = 1L;

protected String content;

protected String createTime;

protected String operation;

protected String username;

protected String operationIp;

@XmlElement(name = "content", required = true,nillable = true)
public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

@XmlElement(name = "createTime", required = true,nillable = true)
public String getCreateTime() {
return createTime;
}

public void setCreateTime(String createTime) {
this.createTime = createTime;
}

@XmlElement(name = "operation", required = true,nillable = true)
public String getOperation() {
return operation;
}

public void setOperation(String operation) {
this.operation = operation;
}

@XmlElement(name = "username", required = true,nillable = true)
public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

@XmlElement(name = "operationIp", required = true,nillable = true)
public String getOperationIp() {
return operationIp;
}

public void setOperationIp(String operationIp) {
this.operationIp = operationIp;
}
}

@XmlAccessorType:便于对象与xml文件之间的转换
@XmlType中:参数propOrder指定映射XML时的节点顺序,使用该属性时,必须列出JavaBean对象中的所有字段,否则会报错。
@XmlRootElement :xml 文件的根元素
@XmlElementWrapper:仅允许出现在集合属性上,使用该注解后,将会在原xml结点上再包装一层xml

@XmlElement:字段,方法,参数级别的注解。该注解可以将被注解的(非静态)字段,或者被注解的get/set方法对应的字段映射为本地元素,也就是子元素。参数 name用于指定映射时的节点名称,指定生成元素的名字,若不指定,默认使用方法名小写作为元素名;参数 required字段是否必须,默认为false;参数 nillable是否处理空数据,默认为false。
其他关于JAXB的注解,大家就根据需要自行百度一下~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
ini复制代码        Submit submit = new Submit();
submit.setTitle(date2Str + "_logs");
//这里给loxList集合赋值
List<LogX> logXList = new ArrayList<>();
submit.setLog(logXList);
JAXBContext jc = null;
ByteArrayOutputStream stream = new ByteArrayOutputStream();
String fileName = submit.getTitle() + ".xml";
ByteArrayOutputStream bis = null;
FileOutputStream fileOutputStream = null;
try {
jc = JAXBContext.newInstance(Submit.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
StringWriter writer = new StringWriter();
marshaller.marshal(submit, writer);
String content = writer.toString().replaceAll(JoinConstant.JAXB_NILL_STR, "");
byte[] bs = content.getBytes("UTF-8");
File file2 = new File(fileName);
fileOutputStream = new FileOutputStream(file2);
file2.createNewFile();
fileOutputStream.write(bs);
fileOutputStream.close();
download(file2, res);
} catch (JAXBException e) {
e.printStackTrace();
throw new RuntimeException("xml生成出错", e);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
try {
if (null != bis) bis.close();
if (null != stream) stream.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}

涉及到的download方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
ini复制代码private void download(File file, HttpServletResponse res) {
String fileName = file.getName();
res.setHeader("content-type", "application/octet-stream");
res.setContentType("application/octet-stream;charset=UTF-8");
res.setHeader("Content-Disposition", "attachment; filename=" + fileName);
byte[] buff = new byte[1024];
BufferedInputStream bis = null;
OutputStream os = null;
try {
os = res.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(
new File(file.getAbsolutePath())));
int i = bis.read(buff);
while (i != -1) {
os.write(buff, 0, buff.length);
os.flush();
i = bis.read(buff);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、导出word

使用freemarker技术在web后台导出word文档:
具体步骤为:

1、设计word模版
2、修改ftl模版
3、 填充数值,导出word模板
4、生成Word模板
生产word模版主要为:一个是把word文档另存为xml文档;然后把xml文档后缀改为ftl文档****
如下图,我所需要的模板为:
在这里插入图片描述
然后使用sublime打开后缀名为ftl的文件,通过sublime插件,将ftl文件格式化,然后找到如下图所示位置进行编辑
在这里插入图片描述
注意${log.xh}等其他的标签的修改

代码如下:

1
2
3
4
5
6
7
8
javascript复制代码        Map<String, Object> beanParams = new HashMap<String, Object>();
//这里给loglist集合赋值
List<LogView> loglist = new ArrayList<>();
String date2Str = DateSearchUtils.date2Str(new Date());
beanParams.put("title", date2Str+"日志信息");
beanParams.put("loglist", loglist);
beanParams.put("attention", "请注意确保所有信息的正确性");
WordExportUtil.WordExportUtil(request, response, WordExportUtil.WORD_2003, "日志信息列表导出", "templateFile.ftl", beanParams,getExcelDir());

涉及到的WordExportUtil.WordExportUtil()方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
ini复制代码    public static String WORD_2007 = "WORD_2007";
public static String WORD_2003 = "WORD_2003";

/**
* 设置下载文件中文件的名称
* @param filename
* @param request
* @return
*/
public static String encodeFilename(String filename, HttpServletRequest request) {
String agent = request.getHeader("USER-AGENT");
try {
if ((agent != null) && (-1 != agent.indexOf("MSIE"))) {
String newFileName = URLEncoder.encode(filename, "UTF-8");
newFileName = StringUtils.replace(newFileName, "+", "%20");
if (newFileName.length() > 150) {
newFileName = new String(filename.getBytes("GB2312"), "ISO8859-1");
newFileName = StringUtils.replace(newFileName, " ", "%20");
}
return newFileName;
}
if ((agent != null) && (-1 != agent.indexOf("Mozilla")))
return MimeUtility.encodeText(filename, "UTF-8", "B");
return URLEncoder.encode(filename, "UTF-8");
} catch (Exception ex) {
return filename;
}
}
/**
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param version Word_2003/Word_2007
* @param docFileName 生成的doc临时文件名
* @param templateFile freemark模板文件名
* @param beanParams 入参数据: Map<String, Object>类型
*/
public static void writeResponse(HttpServletRequest request, HttpServletResponse response, String version, String docFileName, String templateFile, Map<String, Object> beanParams,String getExcelDir) {
writeResponse(request, response, version, "temp", docFileName, "template", templateFile, beanParams, getExcelDir);
}

/**
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param version Word_2003/Word_2007
* @param docTempDir 生成的doc临时文件目录
* @param docFileName 生成的doc临时文件名
* @param templateDir 存放freemark模板的目录
* @param templateFile freemark模板文件名
* @param beanParams 入参数据: Map<String, Object>类型
*/
public static void writeResponse( HttpServletRequest request, HttpServletResponse response, String version, String docTempDir, String docFileName, String templateDir, String templateFile, Map<String, Object> beanParams,String getExcelDir) {
Configuration config = new Configuration();
ServletContext sc = request.getSession().getServletContext();
InputStream is = null;
File previewFile = null;
try {
config.setDirectoryForTemplateLoading(new File(getExcelDir));
config.setObjectWrapper(new DefaultObjectWrapper());
Template template = config.getTemplate(templateFile, "UTF-8");
String date2Str = DateSearchUtils.date2Str(new Date());
String docFileName1 = date2Str+"_logs";
if (WORD_2007.equals(version)) {
docFileName1 = encodeFilename(docFileName1 + ".docx", request);
} else {
docFileName1 = encodeFilename(docFileName1 + ".doc", request);
}
String docName = "D:\\join\\excel"+docFileName;
FileOutputStream fos = new FileOutputStream(docName);
Writer out = new OutputStreamWriter(fos, "UTF-8");
template.process(beanParams, out);
out.flush();
out.close();
previewFile = new File(docName);
is = new FileInputStream(previewFile);
response.reset();
if (WORD_2007.equals(version)) {
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
}else{
response.setContentType("application/vnd.ms-word;charset=UTF-8");
}
response.addHeader("Content-Disposition", "attachment;filename="+docFileName1);
byte[] b = new byte[1024];
int len;
while ((len=is.read(b)) >0) {
response.getOutputStream().write(b,0,len);
}
response.getOutputStream().flush();
response.getOutputStream().close();

} catch (Exception e) {
e.printStackTrace();
}finally{
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(previewFile!=null){
previewFile.delete();
}
}
}
3、导出pdf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
ini复制代码// 新建文件
String date2Str = DateSearchUtils.date2Str(new Date());
String fileName = date2Str + "_logs.pdf";
Document document = new Document();
File file = new File(fileName);
PdfWriter.getInstance(document, new FileOutputStream(file));
document.open();
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);// 中文字体
com.itextpdf.text.Font FontChinese18 = new com.itextpdf.text.Font(bfChinese, 18, com.itextpdf.text.Font.BOLD);
//设置名字
Paragraph pg_bt = new Paragraph("日志列表", FontChinese18);
pg_bt.setAlignment(Element.ALIGN_CENTER);
document.add(pg_bt);
// Font fontChineseBold = new Font(bfChinese, 14, Font.BOLD);//内容字体特殊加粗
Font titleChinese = new Font(bfChinese, 18, Font.BOLD);// 标题字体
// Font noteChinese = new Font(bfChinese, 12, Font.BOLD);//设置内容加粗的区
Font contenttitleChinese = new Font(bfChinese, 12, Font.BOLD);// 内容小标题字体
//这里给logViews 集合赋值
List<LogView> logViews = new ArrayList<>();
// 每行加空白
pg_bt = new Paragraph(" ", titleChinese);
pg_bt.setAlignment(Element.ALIGN_LEFT);
document.add(pg_bt);
SimpleDateFormat start = new SimpleDateFormat("HH:mm");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
PdfPTable table5 = new PdfPTable(2);
int width5[] = {80, 20};
table5.setWidths(width5);
PdfPCell cell51 = new PdfPCell(new Paragraph("日志打印时间 : " + sdf.format(new Date()), contenttitleChinese));
PdfPCell cell52 = new PdfPCell(new Paragraph("", contenttitleChinese));
cell51.setBorder(0);
cell52.setBorder(0);
table5.addCell(cell51);
table5.addCell(cell52);
table5.setHorizontalAlignment(Element.ALIGN_LEFT);
document.add(table5);
//加入空行
Paragraph blankRow51 = new Paragraph(18f, " ", contenttitleChinese);
document.add(blankRow51);
int col = 6;
PdfPTable table = new PdfPTable(col);
BaseColor bc = new BaseColor(102, 204, 255);
//设置表格占PDF文档100%宽度
table.setWidthPercentage(100);
table.setWidths(new int[]{8, 12, 15, 20, 15, 30});
BaseColor lightGrey01 = new BaseColor(0xCC, 0xCC, 0xCC);
PdfPCell cell0 = toPdfPCell("序号", Element.ALIGN_CENTER);
cell0.setBackgroundColor(lightGrey01);
table.addCell(cell0);
PdfPCell cell1 = toPdfPCell("用户名", Element.ALIGN_CENTER);
cell1.setBackgroundColor(lightGrey01);
table.addCell(cell1);
PdfPCell cell2 = toPdfPCell("访问ip", Element.ALIGN_CENTER);
cell2.setBackgroundColor(lightGrey01);
table.addCell(cell2);
PdfPCell cell3 = toPdfPCell("创建时间", Element.ALIGN_CENTER);
cell3.setBackgroundColor(lightGrey01);
table.addCell(cell3);
PdfPCell cell4 = toPdfPCell("操作", Element.ALIGN_CENTER);
cell4.setBackgroundColor(lightGrey01);
table.addCell(cell4);
PdfPCell cell5 = toPdfPCell("日志内容", Element.ALIGN_CENTER);
cell5.setBackgroundColor(lightGrey01);
table.addCell(cell5);
if (logViews.size() > 0) {
for (LogView view : logViews) {
table.addCell(toPdfPCell(view.getXh(), Element.ALIGN_CENTER));
table.addCell(toPdfPCell(view.getUsername(), Element.ALIGN_CENTER));
table.addCell(toPdfPCell(view.getAccessEndIp(), Element.ALIGN_CENTER));
table.addCell(toPdfPCell(DateSearchUtils.longToDate(view.getCreateTime()), Element.ALIGN_CENTER));
table.addCell(toPdfPCell(view.getOperation(), Element.ALIGN_CENTER));
table.addCell(toPdfPCell(view.getContent(), Element.ALIGN_CENTER));
}
}
document.add(table);
document.close();
download(file, res);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

涉及到的toPdfPCell()方法如下:

1
2
3
4
5
6
7
8
java复制代码public PdfPCell toPdfPCell(String name, int align) throws DocumentException, IOException {
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);// 中文字体
Font fontChinese = new Font(bfChinese, 12, Font.NORMAL);// 内容字体
PdfPCell cell = new PdfPCell(new Paragraph(name, fontChinese));
cell.setHorizontalAlignment(align);// 设置内容水平居中显示
cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 设置垂直居中
return cell;
}
4、导出excel

参考地址:easypoi.mydoc.io/

5、所需的maven依赖为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
xml复制代码<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>com.yulintu</groupId>
<artifactId>common-excel</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>5.2.0.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>RELEASE</version>
</dependency>

效果图如下:

6、导出的xml格式的文件内容如下:

在这里插入图片描述

7、导出的word格式的文件内容如下:

在这里插入图片描述

8、导出的pdf格式的文件内容如下:

在这里插入图片描述

9、导出的excel格式的文件内容如下:

在这里插入图片描述

写在最后:可能在进行这个功能实现时,我所采用的方法并不是最合理的,大家一起学习嘛

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%