业务要求: 网站页面内容导出为相关分析报告,内容包括文本描述,分析表格【行,列内容不固定】,echars图表等
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.17version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-scratchpadartifactId>
<version>3.17version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxml-schemasartifactId>
<version>3.17version>
dependency>
List<String> listColumns = new ArrayList<>();
List<List<String>> listLineData = new ArrayList<>();
//map中 img为base64格式字符串 item作为图片字描述的key
List<Map<String,String>> listPicContent = new ArrayList<>()
//图片处理
//处理页面所需图片存至服务器
for (int s = 0; s < listPicContent .size(); s++) {
//base64字符串格式过长,后台采用StringBuffer接收
StringBuffer img =
new StringBuffer(listPicContent .get(s).get("img"));
Base64ToPicUtils.convertBase64ToImage(img,s + "");
}
//创建word文档对象
XWPFDocument document = new XWPFDocument();
//创建文本标题
XWPFParagraph title = document.createParagraph();
//设置段落居中
title.setAlignment(ParagraphAlignment.CENTER);
XWPFRun titleRun = title.createRun();
titleRun.setFontSize(20);
titleRun.setFontFamily("宋体");
titleRun.setBold(true);
titleRun.setText("word文档标题");
titleRun.addBreak(); //换行
//添加内容段落 首先展示分析表格
XWPFParagraph paragraph = document.createParagraph();
paragraph.setAlignment(ParagraphAlignment.valueOf(STJc.INT_LEFT));
XWPFRun firstRun = paragraph.createRun();
firstRun .setFontSize(17);
firstRun .setFontFamily("黑体");
firstRun .addTab();
firstRun .setText("表格标题描述***分析报表");
//创建表格的第一步
//创建列数,listColumns表示表格列头数据封装集合
XWPFTable table = document.createTable(1,listColumns.size());
//设置表格居中展示
CTJc jc = table.getCTTbl().getTblPr().getJc();
if(jc == null){
jc = table.getCTTbl().getTblPr().addNewJc();
}
jc.setVal(STJc.CENTER);
//设置列头信息
table.getRow(0).setHeight(500);
for (int i=0; i<listColumns.size(); i++){
setCellText(table.getRow(0).getCell(i),listColumns.get(i),null,1000);
}
//表格内容: 行首及内容信息
Integer j = 0;
for (int index = 0; index < listLineData.size(); index++) { //listLineData 表示行数据集合
//这个是在表格的添加,添加到第几行
List<String> item = listLineData.get(index);
XWPFTableRow row = table.insertNewTableRow(j+1);
//设置单元格高
row.setHeight(1000);
for (int i = 0; i < listColumns.size(); i++ ) {
XWPFTableCell cell = row.createCell();
CTTc ctTc = cell.getCTTc();
CTTcPr ctTcPr = ctTc.addNewTcPr();
ctTcPr.addNewTcW().setW(BigInteger.valueOf(1000));
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
if(StringUtils.isNotBlank(item.get(i))){
cell.setText(item.get(i)); //单元格文本填充
}else{
cell.setText(null);
}
}
}
/**
* 接上文代码, 图片文字组合部分导出
* 页面图表转化为base64格式后传至后端,
* 未找到poi直接解析base64格式的方法,
* 现将base64格式解析为图片存至服务器,
* poi引入对应图片
*/
for(int x = 0; x < listPicContent.size(); x++){
XWPFParagraph paragraph1 = document.createParagraph();
//设置之段落左对齐
paragraph1.setAlignment(ParagraphAlignment.valueOf(STJc.INT_LEFT));
//
XWPFRun firstRun = paragraph1.createRun();
firstRun.setFontSize(13);
firstRun.setFontFamily("黑体");
firstRun.addTab();
//存储图片名称对应数据下标 便于实现数据与文本对应
String picName = "D://Temp//" + x + ".png" ; //测试服务器地址即可
File file = new File(picName);
if(file.exists()){
createPicture(document,picName); //写入图片
}
firstRun.setText((x+1)+ "、" + listPicContent.get(x).get("item")); // 序号+写入图片对应文字
firstRun.addBreak(); //换行
firstRun.addTab();
firstRun.addBreak(); //换行
}
//路径问题处理
String path = "D://Temp//";
File savefile = new File(path);
if (!savefile.exists()) {
savefile.mkdirs();
}
String flieName = path + "xxxx分析报告"+".docx";
FileOutputStream fos = new FileOutputStream(flieName);
document.write(fos);
fos.close();
FileUtil.downloadFile(fileName,response);//执行下载
/**
*
* @param doc
* @param picPath
* @throws InvalidFormatException
* @throws IOException
*/
public void createPicture(XWPFDocument doc, String picPath) throws InvalidFormatException, IOException, org.apache.poi.openxml4j.exceptions.InvalidFormatException {
XWPFParagraph paraX = doc.createParagraph();
XWPFRun run = paraX.createRun();
FileInputStream is = new FileInputStream(picPath);
int picType = -1;
//判断图片类型
String suffix = picPath.substring(picPath.lastIndexOf(".")+1);
if(suffix.equals("png")) picType = XWPFDocument.PICTURE_TYPE_PNG;
else if(suffix.equals("jpg")) picType = XWPFDocument.PICTURE_TYPE_JPEG;
run.addPicture(is, picType, picPath, Units.toEMU(300), Units.toEMU(200));
is.close();
}
import java.awt.image.BufferedImage;
import java.io.*;
public class Base64ToPicUtils {
private static String PATH = "D:\\Temp\\"; //图片转存路径
public static void convertBase64ToImage(StringBuffer base64Code,String name){
String str = base64Code.toString();
BufferedImage image = null;
byte[] imageByte = null;
if(StringUtils.isNotBlank(str)){
int i = str.indexOf(",");
String s = str.subSequence(i+1, str.length()).toString();
String replace = s.replace(" ", "+");
try {
BASE64Decoder decoder = new BASE64Decoder();
byte[] imgbyte = decoder.decodeBuffer(s);
String aa = PATH + name + ".png";
OutputStream os = new FileOutputStream(aa);
os.write(imgbyte, 0, imgbyte.length);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.sdyy.common.utils;
import cn.hutool.core.io.IoUtil;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import sun.misc.BASE64Decoder;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;
import java.util.UUID;
public class FileUtil {
public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
File targetFile = new File(filePath);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
FileOutputStream out = new FileOutputStream(filePath + fileName);
out.write(file);
out.flush();
out.close();
}
public static boolean deleteFile(String fileName) {
File file = new File(fileName);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public static String renameToUUID(String fileName) {
return UUID.randomUUID() + "." + fileName.substring(fileName.lastIndexOf(".") + 1);
}
/**
* 创建目录
*/
public static void createDir(String fileSavePath) {
File file = new File(fileSavePath);
if (!file.exists()) {
file.mkdirs();
}
}
public static File doc2pdf(File file, String docPath) throws Exception {
//1.设置凭证
String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "static/docs/license.xml";
InputStream license = new FileInputStream(basePath);// 凭证文件
License aposeLic = new License();
aposeLic.setLicense(license);
//2.进行转换
FileInputStream input = new FileInputStream(file);
String fileName = file.getName().replace("docx", "") + "pdf";
File pdf = new File(docPath + fileName);
OutputStream out = new FileOutputStream(pdf);
Document doc = new Document(input); //Address是将要被转化的word文档
doc.save(out, SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
IoUtil.close(input);
IoUtil.close(out);
IoUtil.close(license);
return pdf;
}
//
public static void downloadFile2(String filePath, HttpServletResponse response) {
// 声明工具类
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {
// 若路径为空
if (StringUtils.isEmpty(filePath)) {
throw new Exception("invalid filepath of null.");
}
// 没找到文件
File file = new File(filePath);
if (!file.exists()) {
throw new Exception("file not exist in path [" + filePath + "]");
}
// 获取文件名
String fileName = file.getName();
// 输出文件流到浏览器
in = new BufferedInputStream(new FileInputStream(filePath));
out = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/x-download;charset=utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
byte[] buffer = new byte[8192];
int count = 0;
while ((count = in.read(buffer, 0, 8192)) != -1) {
out.write(buffer, 0, count);
}
out.flush();
file = null;
} catch (Exception e) {
e.printStackTrace();
} finally {
closeStream(in, out);
}
}
/**
* 关闭输入输出流
*/
public static void closeStream(InputStream in, OutputStream out) {
if (null != in) {
try {
in.close();
} catch (IOException e) {
// e.printStackTrace();
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
// e.printStackTrace();
}
}
}
public static String downloadFile(String filePath,HttpServletResponse response) throws UnsupportedEncodingException {
String[] strArray=filePath.split("//");
String filename=strArray[strArray.length-1];
response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
response.setCharacterEncoding("UTF-8");
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
try {
response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(filename, "UTF-8"));
} catch (UnsupportedEncodingException e2) {
e2.printStackTrace();
}
byte[] buff = new byte[1024];
BufferedInputStream bis = null;
OutputStream os = null;
try {
os = response.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(new File(filePath)));
int i = bis.read(buff);
while (i != -1) {
os.write(buff, 0, buff.length);
os.flush();
i = bis.read(buff);
}
} catch (FileNotFoundException e1) {
return "系统找不到指定的文件";
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "success";
}
/**
* base64字符串转化成图片
* @param imgStr
* @return
*/
public static String GenerateImage(String imgFile,String imgStr) { //对字节数组字符串进行Base64解码并生成图片
String type = "png";
if (StringUtils.isBlank(imgStr)) //图像数据为空
return "false";
BASE64Decoder decoder = new BASE64Decoder();
try
{
//获取图片类型
String[] splitData = imgStr.split(";base64,");
if(splitData.length == 1) {
imgStr = splitData[0];
}else {
type = splitData[0].split("/")[1];
imgStr = splitData[1];
}
//Base64解码
byte[] b = decoder.decodeBuffer(imgStr);
for(int i=0;i<b.length;++i)
{
if(b[i]<0)
{//调整异常数据
b[i]+=256;
}
}
//生成jpeg图片
String imgFilePath = imgFile + "." +type;//新生成的图片
OutputStream out = new FileOutputStream(imgFilePath);
out.write(b);
out.flush();
out.close();
return imgFilePath;
}
catch (Exception e)
{
return "false";
}
}
/**
* 删除文件夹(强制删除)
*
* @param path
*/
public static void deleteAllFilesOfDir(File path) {
if (null != path) {
if (!path.exists())
return;
if (path.isFile()) {
boolean result = path.delete();
int tryCount = 0;
while (!result && tryCount++ < 10) {
System.gc(); // 回收资源
result = path.delete();
}
}
File[] files = path.listFiles();
if (null != files) {
for (int i = 0; i < files.length; i++) {
deleteAllFilesOfDir(files[i]);
}
}
path.delete();
}
}
}
/**
* 将多个canvas画布组成的图表合成为一个完整的canvas,并获取完整的dataURl
* @param divId divId 包含整个画布的divId
* @returns {String} widthXheight@dataURL 例:
* 400X300@data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA
*/
function getFullCanvasDataURL(divId){
debugger;
//将第一个画布作为基准。
var baseCanvas = $("#"+divId).find("canvas").first()[0];
if(!baseCanvas){
return false;
};
var width = baseCanvas.width;
var height = baseCanvas.height;
var ctx = baseCanvas.getContext("2d");
// const imageData = ctx.getImageData(0, 0,width,height);
// for (let i = 0; i < imageData.data.length; i += 4) {
// // 当该像素是透明的,则设置成白色
// if (imageData.data[i + 3] === 0) {
// imageData.data[i] = 255;
// imageData.data[i + 1] = 255;
// imageData.data[i + 2] = 255;
// imageData.data[i + 3] = 255;
// }
// }
// ctx.putImageData(imageData, 0, 0);
// var dataURL = canvasDom.toDataURL('image/png');
//遍历,将后续的画布添加到在第一个上
$("#"+divId).find("canvas").each(function(i,canvasObj){
if(i>0){
var canvasTmp = $(canvasObj)[0];
ctx.drawImage(canvasTmp,0,0,width,height);
}
});
//获取base64位的url
return baseCanvas.toDataURL('image/png');
}
END 导出文件效果