②. SpirngBoot集成deepoove-Poi-ti插件
本插件主要是用于word内容的替换,本文使用fastDFS对文件进行存取,提供上传和下载,具有很高的实践意义。
文档官网:http://deepoove.com/poi-tl/
1、创建maven工程,引入依赖:
父工程:我们这里需要使用springBoot做一个简单的文件下载,所以引入springboot的官方父工程。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<!-- fastDfs的依赖-->
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27-SNAPSHOT</version>
<exclusions>
<exclusion>
<!-- 移除冲突的jar包-->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 插件官方的依赖-->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.7.3</version>
<exclusions>
<exclusion>
<!--移除冲突的jar包-->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 方便使用单元测试,引入了junit的工具类-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- 使用了IOUtil的工具类,所以引入了common-io的工具类-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- 使用了servetOutPutStream,所以引入servlet的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
友情提示,当我们的jar包冲突的时候,可以在maven的界面找到冲突的家暴的groupId和artifactId,在进行移除就可以了。
在resources下面配置spring的配置文件(application.yml),和fastDFS的配置文件tracker.conf
server:
port: 8085 //我们修改一个tomcat的端口
#远程的fastDFS地址,我这里使用的是阿里云的地址。
tracker_server=39.107.45.130:22122
#连接超时时间,针对socket套接字函数connect,默认为30秒
connect_timeout=30000
#网络通讯超时时间,默认是60秒
network_timeout=60000
创建springBoot的启动类
@SpringBootApplication
//@ComponentScan(basePackages = "com",excludeFilters = {
// @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {Log4jLoggerFactory.class})
//})
public class SpringPoiItBootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringPoiItBootApplication.class,args);
}
}
这里需要注意的是,我们配置的ComponentScan的basePackages不能跟主启动类的包名一致,这样没有任何意义。
我们来测试一下我们的上传和下载:
public static void main(String[] args) throws IOException {
//初始化模板文件
File file = new File("D:\\template.docx");
//设置对应在word上面的值,详细可以参考文档。
XWPFTemplate template = XWPFTemplate.compile(file).render(new HashMap<String, Object>() {{
put("name", "吴涛涛");
put("nian", "2020");
put("month", "3");
}});
// File fileOut = new File("F:\\template.docx");
// FileOutputStream out = new FileOutputStream(fileOut);
// 这里把文件转换成byte数组、
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
template.write(byteArrayOutputStream);
byte[] bytes = byteArrayOutputStream.toByteArray();
Map<String, Object> map = uploadWord(bytes);
String name = (String) map.get("fileName");
//打印出上传的地址。
System.out.println(name);
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
template.close();
}
private static Map<String, Object> uploadWord(byte[] inByte) {
Map<String, Object> result = new HashMap();
try {
//本来想去修改这里的代码,想了想,还是不改了,玩意出问题咋个搞呀。
ClientGlobal.init("tracker.conf");
//获取一个trackerClient,并且获得连接;
TrackerClient trackerClient = new TrackerClient();
TrackerServer connection = trackerClient.getConnection();
//获取storageClient的对象;
StorageClient storageClient = new StorageClient(connection, null);
//上传图片到fastdfs服务器;
String[] jpgs = storageClient.upload_file(inByte, "docx", null);
String Imagepath = "http://39.107.45.103:8001/";
for (int i = 0; i < jpgs.length; i++) {
if (i == 0) {
Imagepath += jpgs[i];
Imagepath += "/";
continue;
}
Imagepath += jpgs[i];
}
//返回地址。
result.put("fileName", Imagepath);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Test
public void testDownload() {
try {
ClientGlobal.init("tracker.conf");
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getConnection();
StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
//从fastdfs中下载文件。
byte[] b = storageClient.download_file("group1", "M00/00/00/rBHE-F6B_ECAS_OVAABBXwFPDt879.docx");
//把一个字节数组转换成一个文件,并写出。
File fileOut = new File("F:\\template.docx");
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fileOut));
stream.write(b);
stream.flush();
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
我们在handler中尝试能不能下载:
@RequestMapping("test")
@ResponseBody
public void getTest(HttpServletRequest request, HttpServletResponse response) throws Exception {
byte[] data = testDownload();
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("项目申报书.docx", "UTF-8"));
// 写出
ServletOutputStream outputStream = response.getOutputStream();
IOUtils.write(data, outputStream);
}
@Test
public byte[] testDownload() {
try {
ClientGlobal.init("tracker.conf");
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getConnection();
StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
byte[] b = storageClient.download_file("group1", "M00/00/00/rBHE-F6B_ECAS_OVAABBXwFPDt879.docx");
return b;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
访问这个Handler就会实现下载;
扩展知识:
IOUtil.write相当与outputStream.write(data);
IOUtil源码如下:
public static void write(byte[] data, OutputStream output)
throws IOException {
if (data != null) {
output.write(data);
}
}
Http响应头:
Location: http://www.it315.org/index.jsp -表示重定向的地址,该头和302的状态码一起使用。
Server:apache tomcat ---表示服务器的类型
Content-Encoding: gzip -- 表示服务器发送给浏览器的数据压缩类型
Content-Length: 80 --表示服务器发送给浏览器的数据长度
Content-Language: zh-cn --表示服务器支持的语言
Content-Type: text/html; charset=GB2312 --表示服务器发送给浏览器的数据类型及内容编码
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT --表示服务器资源的最后修改时间
Refresh: 1;url=http://www.it315.org --表示定时刷新
Content-Disposition: attachment; filename=aaa.zip --表示告诉浏览器以下载方式打开资源(下载文件时用到)
Transfer-Encoding: chunked
Set-Cookie:SS=Q0=5Lb_nQ; path=/search --表示服务器发送给浏览器的cookie信息(会话管理用到)
Expires: -1 --表示通知浏览器不进行缓存
Cache-Control: no-cache
Pragma: no-cache
Connection: close/Keep-Alive
Content-Type: text/html; charset=GB2312
Content-Disposition: attachment; filename=aaa.zip
这两句话告诉浏览器,我们用什么格式的编码,并且告诉浏览器以下载的方式打开文件;
我们可以用这两句代码来实现:URLEncoder.encode是防止中文乱码。
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("项目申报书.docx", "UTF-8"));
这只是一个小小的demo,还有更多好玩的东西,请自己去文档中找寻。