这是我的第一篇分享,希望以后遇到新的问题和功能我能够及时的记录下来与大家一起分享。
首先是js部分:
这一块在后台处理的时候遇到了好多的问题,hightcharts我用的是最新的版本,highcharts本身自带获取svg的方法,因为highcharts的在浏览器生成图片主要使用的是svg,我查了一下说这个和ie浏览器有很大的关系。我们获取到svg之后要交给后台来进行处理,过程中发现会报错,找了好久,发现是highcharts生成的svg里面有style,后台做处理的时候会报错,所以自己在这进行了处理,后面根据自己的需求去掉了标题。
function GetHighchartsSvg(div){
var chart = div.highcharts();
var svg = chart.getSVG();
var y =svg.indexOf("style");
var s =svg.indexOf("xmlns=");
var a =svg.substring(0,y);
var b =svg.substring(s,svg.length);
var c = b.indexOf("<text");
var d = b.indexOf("</text>");
var e =b.substring(0,c);
var f =b.substring(d+7,b.length);
var k =e+f;
var str = a+k;
alert(str)
str=str.replace(/</g,'\n<').replace(/>/g, '>');
svgList.push(str);
}
因为我的页面上有很多个饼状图,所以这里把获取的svg作了处理再传给后台。
$("#exportWord").click(function(){
var svg = svgList.join("_");
$("#svg").html(svg);//给form表单textarea赋值(form表单我就不贴了,不解释···)
$("#formid").submit();//提交form表单
});
下面是后台部分,后台开始也是借鉴的别人的处理类,但是处理的时候总报错。发现是svg有问题。
https://blog.youkuaiyun.com/zwx19921215/article/details/34442593这是借鉴地址。
标题我是在创建图片的时候按照自己的需求添加的每个图片的标题,因为hightcharts生成的svg图片的标题没有换行功能,标题过长的话就会显示不全。生成word用的是先生成png图片再往word中插入的方式。生成的文件夹可以自行保存,也可以之后删除掉。
@RequestMapping(value = "/ExportPaperWord", method = RequestMethod.POST)
public void ExportPaperWord(HttpServletRequest request,HttpServletResponse response) throws Exception{
String svg = request.getParameter("svg");
String paperId=request.getParameter("paperId");
FeedbackPaper feedbackPaper = this.reportService.getPaperById(Integer.valueOf(paperId));
List<FeedbackQuestion> questionList = this.reportService.getFeedbackQuestion(Integer.valueOf(paperId));
String [] svgList = svg.split("_");
String webRootPath = System.getProperty("campusManage.webapp");
Calendar calendar = Calendar.getInstance();
String relativePath ="PNG" +"/" + calendar.get(Calendar.YEAR) + "/" + (calendar.get(Calendar.MONTH) + 1) + "/" + calendar.get(Calendar.DATE) + "/";
String savePath = webRootPath + File.separator + relativePath;
File dir = new File(savePath);
if (!dir.exists())
dir.mkdirs();
System.out.println(svg);
CustomXWPFDocument doc = new CustomXWPFDocument(); //创建文档实体
XWPFParagraph title = doc.createParagraph(); //创建一个段落
title.setAlignment(ParagraphAlignment.CENTER); //设置段落的位置
XWPFRun r1 = title.createRun(); //设置相同样式的文本
r1.setBold(true); //设置字体是否加粗
r1.setFontFamily("宋体"); //设置字体
r1.setText(feedbackPaper.getName()); //添加文字内容
r1.setFontSize(16); //设置字体大小
//生成png图片,循环生成多个
for(int i=0;i<svgList.length;i++){
String str=svgList[i];
//插入图片文件,同样需要新建一个段落实体
XWPFParagraph pic = doc.createParagraph();
pic.setAlignment(ParagraphAlignment.CENTER);
XWPFRun r2 = pic.createRun(); //设置相同样式的文本
// r2.setBold(true); //设置字体是否加粗
r2.setFontFamily("宋体"); //设置字体
r2.setText(questionList.get(i).getName()); //添加文字内容
r2.setFontSize(14); //设置字体大小
String fileName = dir.getAbsolutePath() + File.separator +i+".png";
SvgPngUtil.convertToPng(str,fileName);
doc.addPictureData(new FileInputStream(fileName),XWPFDocument.PICTURE_TYPE_PNG);
doc.createPicture(pic,doc.getAllPictures().size()-1, 600, 400," ");
}
// doc.addPictureData(new FileInputStream("e://svg2.png"),XWPFDocument.PICTURE_TYPE_PNG);
// doc.createPicture(pic,doc.getAllPictures().size()-1, 600, 400," ");
//判断添加的图片的类型
int res = XWPFDocument.PICTURE_TYPE_PICT;
res = XWPFDocument.PICTURE_TYPE_PNG;
//通过respons输出提示框下载文件,要注意的是如果文件名称中有文字,需要对文件名称进行URLEncoder编码
String fileName = feedbackPaper.getName();
OutputStream out= response.getOutputStream();
response.setHeader("Content-Type","application/ms-winword");
response.addHeader("Content-Disposition","attachment;filename=\""+ URLEncoder.encode(fileName,"UTF-8")+ ".docx\"");
response.setContentType("application/octet-stream");
response.setCharacterEncoding("UTF-8");
doc.write(out);
out.close();
}
package com.framework.util;
import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
public class CustomXWPFDocument extends XWPFDocument {
public CustomXWPFDocument(InputStream in) throws IOException {
super(in);
}
/**
*
*/
public CustomXWPFDocument() {
super();
// TODO Auto-generated constructor stub
}
/**
* @param pkg
* @throws IOException
*/
public CustomXWPFDocument(OPCPackage pkg) throws IOException {
super(pkg);
// TODO Auto-generated constructor stub
} // picAttch 图片后面追加的字符串 可以是空格
public void createPicture(XWPFParagraph paragraph,int id, int width, int height,String picAttch) {
final int EMU = 9525;
width *= EMU;
height *= EMU;
String blipId = getAllPictures().get(id).getPackageRelationship()
.getId();
CTInline inline = paragraph.createRun().getCTR()
.addNewDrawing().addNewInline();
paragraph.createRun().setText(picAttch);
String picXml = ""
+ "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
+ " <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
+ " <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
+ " <pic:nvPicPr>" + " <pic:cNvPr id=\""
+ id
+ "\" name=\"Generated\"/>"
+ " <pic:cNvPicPr/>"
+ " </pic:nvPicPr>"
+ " <pic:blipFill>"
+ " <a:blip r:embed=\""
+ blipId
+ "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
+ " <a:stretch>"
+ " <a:fillRect/>"
+ " </a:stretch>"
+ " </pic:blipFill>"
+ " <pic:spPr>"
+ " <a:xfrm>"
+ " <a:off x=\"0\" y=\"0\"/>"
+ " <a:ext cx=\""
+ width
+ "\" cy=\""
+ height
+ "\"/>"
+ " </a:xfrm>"
+ " <a:prstGeom prst=\"rect\">"
+ " <a:avLst/>"
+ " </a:prstGeom>"
+ " </pic:spPr>"
+ " </pic:pic>"
+ " </a:graphicData>" + "</a:graphic>";
// CTGraphicalObjectData graphicData =
inline.addNewGraphic().addNewGraphicData();
XmlToken xmlToken = null;
try {
xmlToken = XmlToken.Factory.parse(picXml);
} catch (XmlException xe) {
xe.printStackTrace();
}
inline.set(xmlToken);
// graphicData.set(xmlToken);
inline.setDistT(0);
inline.setDistB(0);
inline.setDistL(0);
inline.setDistR(0);
CTPositiveSize2D extent = inline.addNewExtent();
extent.setCx(width);
extent.setCy(height);
CTNonVisualDrawingProps docPr = inline.addNewDocPr();
docPr.setId(id);
docPr.setName("图片" + id);
docPr.setDescr("");
}
}
package com.framework.util;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
/**
*@Description:
*@Author:wangyaoyao
*@Since:20180727
*/
public class SvgPngUtil {
/**
*@Description: 将svg字符串转换为png
*@Author:
*@param svgCode svg代码
*@param pngFilePath 保存的路径
*@throws IOException io异常
*@throws TranscoderException svg代码异常
*/
public static void convertToPng(String svgCode,String pngFilePath) throws IOException,TranscoderException{
File file = new File (pngFilePath);
FileOutputStream outputStream = null;
try {
file.createNewFile ();
outputStream = new FileOutputStream (file);
convertToPng (svgCode, outputStream);
} finally {
if (outputStream != null) {
try {
outputStream.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
/**
*@Description: 将svgCode转换成png文件,直接输出到流中
*@param svgCode svg代码
*@param outputStream 输出流
*@throws TranscoderException 异常
*@throws IOException io异常
*/
public static void convertToPng(String svgCode,OutputStream outputStream) throws TranscoderException,IOException{
try {
byte[] bytes = svgCode.getBytes ("UTF-8");
PNGTranscoder t = new PNGTranscoder ();
TranscoderInput input = new TranscoderInput (new ByteArrayInputStream (bytes));
TranscoderOutput output = new TranscoderOutput (outputStream);
t.transcode (input, output);
outputStream.flush ();
} finally {
if (outputStream != null) {
try {
outputStream.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
}
jar包用的是:itext-4.2.1.jar、batik-all-1.10.jar、xml-apis-ext-1.3.04.jar
最开始就是因为jar搞了半天,这里详细记录一下。大家可以自己下载。如果想直接下载的话我这也给出链接
https://download.youkuaiyun.com/download/qq919913883/10568626
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-all</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.lucee</groupId>
<artifactId>xml-apis-ext</artifactId>
<version>1.3.04</version>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>4.2.1</version>
</dependency>