使用htmlunit读取带有echarts的页面,调用js生成svg,再调用batik库将svg转换成png图片
resources下准备一个echarts.html
<html>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<head>
<script src="jquery-3.6.0.min.js"></script>
<script src="echarts.js"></script>
</head>
<body>
<!--准备一个DOM-->
<div id="echartsDemo" style="height:500px;width:1000px"></div>
</body>
<script>
var echartsDemo= null;
$(function () {
// 基于准备好的dom,初始化echarts实例
echartsDemo = echarts.init(document.getElementById('echartsDemo'), null, {
renderer: 'svg',
ssr: true,
width: 400,
height: 300
});
});
</script>
</html>
注意echarts的配置需要用,渲染模式为svg renderer: 'svg'
同目录下放 github.com/apache/echa… 和Jquery jquery.com/download/
Maven:
<dependencies>
<dependency>
<groupId>org.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-transcoder</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-swing</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-codec</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>xmlgraphics-commons</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
代码:
package org.example;
import org.apache.batik.anim.dom.SAXSVGDocumentFactory;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.batik.util.XMLResourceDescriptor;
import org.htmlunit.WebClient;
import org.htmlunit.html.HtmlPage;
import org.w3c.dom.Document;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class Main {
public static Document parseSVGFromString(String svgString) {
try {
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
return factory.createDocument(null, new ByteArrayInputStream(svgString.getBytes("UTF-8")));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String getSVGText(String options, int width, int height) {
try (final WebClient webClient = new WebClient()) {
ClassLoader classLoader = Main.class.getClassLoader();
URL resourceUrl = classLoader.getResource("echarts.html");
URI resourceUri = resourceUrl.toURI();
final HtmlPage page = webClient.getPage(resourceUri.toURL());
// 设置图像大小
page.executeJavaScript("echartsDemo.resize({width:" + width + ",height:" + height + "})");
page.executeJavaScript("echartsDemo.setOption( " + options + ")");
return page.executeJavaScript("echartsDemo.renderToSVGString()").getJavaScriptResult().toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void svgToPng(String svgText) {
try {
// 创建JSVGCanvas并渲染SVG
JSVGCanvas canvas = new JSVGCanvas();
canvas.setDocument(parseSVGFromString(svgText));
// 创建PNGTranscoder以将SVG转换为PNG
PNGTranscoder transcoder = new PNGTranscoder();
TranscoderInput input =
new TranscoderInput(new ByteArrayInputStream(svgText.getBytes(StandardCharsets.UTF_8)));
// 设置PNG输出参数
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
TranscoderOutput output = new TranscoderOutput(outputStream);
// 执行转码并保存图像
transcoder.transcode(input, output);
// 可以直接使用byte
byte[] pngImageData = outputStream.toByteArray();
// 也可以将图像数据的字节数组输出到文件
try (FileOutputStream fos = new FileOutputStream("output_image.png")) {
fos.write(pngImageData);
System.out.println("PNG 图像数据已成功写入到文件 output_image.png");
} catch (IOException e) {
System.err.println("写入文件时出现异常: " + e.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String options =
"{\n" + " xAxis: {\n" + " type: 'category',\n" + " data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']\n" + " },\n" + " yAxis: {\n" + " type: 'value'\n" + " },\n" + " series: [\n" + " {\n" + " data: [120, 200, 150, 80, 70, 110, 130],\n" + " type: 'bar',\n" + " showBackground: true,\n" + " backgroundStyle: {\n" + " color: 'rgba(180, 180, 180, 0.2)'\n" + " }\n" + " }\n" + " ]\n" + "}";
String svgText = getSVGText(options, 500, 500);
svgToPng(svgText);
}
}
生成效果
options配置同官方样例:echarts.apache.org/examples/zh…