将ECharts图表插入到Word文档中

文章目录

    • 在后端调用JS代码
    • 准备ECharts库
    • 生成Word文档
    • 项目地址
      • 库封装
      • 本文示例 EChartsGen_DocTemplateTool_Sample

如何通过ECharts在后台生成图片,然后插入到Word文档中?

首先要解决一个问题:总所周知,ECharts是前端的一个图表库,如何在后台调用JS代码?这里就要用到PhantomJS了。

PhantomJS是一个基于WebKit的JavaScript API,它使用QtWebKit作为核心浏览器的功能,使用WebKit编译、解释和执行JavaScript代码。任何可以在基于WebKit的浏览器上做的事情,它都能做到。它不仅是一个隐形的浏览器,提供了诸如CSS选择器、支持Web标准、DOM操作、JSON、HTML5、Canvas、SVG等功能,同时也提供了处理文件I/O的操作。

之前写过一个文档模板工具,其中可以通过占位符插入图片。

用PhantomJS生成ECharts图表的Png图片,利用文档模板工具插入图片即可实现这个需求。

下面就来看看如何实现。

在后端调用JS代码

创建一个.netstandard2.1的类库项目。为了方便调用,我们安装一个PhantomJS包装器:NReco.PhantomJS

dotnet add package NReco.PhantomJS --version 1.1.0

这只是一个包装器,因此还需要一个可执行文件,前往官网下载PhantomJS。

因为直接使用编译好的可执行文件,因此需要下载对应的平台版本,这里我下载了Windows以及Linux 64-bit版本。

将下载好的可执行文件解压放置在项目根目录下的libs目录中。

在这里插入图片描述

这样我们可以直接在.net中调用PhantomJS了。

在这里插入图片描述

准备ECharts库

jQuery

下载jquery-3.6.3.min.js: https://code.jquery.com/jquery-3.6.3.min.js

ECharts

下载echarts.min.js: https://github.com/apache/echarts/tree/5.4.3/dist

ECharts转换器

echarts-convert在github上有众多版本,echarts-convert的代码来源于这里:https://github.com/wadezhan/billfeller.github.io/issues/85

这里选择

(function () {var system = require('system');var fs = require('fs');var config = {// define the location of js filesJQUERY: 'jquery-3.6.3.min.js',//ESL: 'esl.js',ECHARTS: 'echarts.min.js',// default container width and heightDEFAULT_WIDTH: '1920',DEFAULT_HEIGHT: '800'}, parseParams, render, pick, usage;usage = function () {console.log("\nUsage: phantomjs echarts-convert.js -options options -outfile filename -width width -height height"+ "OR"+ "Usage: phantomjs echarts-convert.js -infile URL -outfile filename -width width -height height\n");};pick = function () {var args = arguments, i, arg, length = args.length;for (i = 0; i < length; i += 1) {arg = args[i];if (arg !== undefined && arg !== null && arg !== 'null' && arg != '0') {return arg;}}};parseParams = function () {var map = {}, i, key;console.log("--logs:\n")console.log(system.args)if (system.args.length < 2) {usage();phantom.exit();}for (i = 0; i < system.args.length; i += 1) {if (system.args[i].charAt(0) === '-') {key = system.args[i].substr(1, i.length);if (key === 'infile') {// get string from file// force translate the key from infile to options.key = 'options';try {map[key] = fs.read(system.args[i + 1]).replace(/^\s+/, '');} catch (e) {console.log('Error: cannot find file, ' + system.args[i + 1]);phantom.exit();}} else {map[key] = system.args[i + 1].replace(/^\s+/, '');}}}return map;};render = function (params) {var page = require('webpage').create(), createChart;var bodyMale = config.SVG_MALE;page.onConsoleMessage = function (msg) {console.log(msg);};page.onAlert = function (msg) {console.log(msg);};createChart = function (inputOption, width, height, config) {var counter = 0;function decrementImgCounter() {counter -= 1;if (counter < 1) {console.log(messages.imagesLoaded);}}function loadScript(varStr, codeStr) {var script = $('<script>').attr('type', 'text/javascript');script.html('var ' + varStr + ' = ' + codeStr);document.getElementsByTagName("head")[0].appendChild(script[0]);if (window[varStr] !== undefined) {console.log('Echarts.' + varStr + ' has been parsed');}}function loadImages() {var images = $('image'), i, img;if (./Assets/images.length > 0) {counter = images.length;for (i = 0; i < images.length; i += 1) {img = new Image();img.onload = img.onerror = decrementImgCounter;img.src = images[i].getAttribute('href');}} else {console.log('The images have been loaded');}}// load opitonsif (inputOption != 'undefined') {// parse the optionsloadScript('options', inputOption);// disable the animationoptions.animation = false;}// we render the image, so we need set background to white.$(document.body).css('backgroundColor', 'white');var container = $("<div>").appendTo(document.body);container.attr('id', 'container');container.css({width: width,height: height});// render the chartvar myChart = echarts.init(container[0]);myChart.setOption(options);// load imagesloadImages();return myChart.getDataURL();};// parse the paramspage.open("about:blank", function (status) {// inject the dependency jspage.injectJs(config.ESL);page.injectJs(config.JQUERY);page.injectJs(config.ECHARTS);var width = pick(params.width, config.DEFAULT_WIDTH);var height = pick(params.height, config.DEFAULT_HEIGHT);// create the chartvar base64 = page.evaluate(createChart, params.options, width, height, config);//fs.write("base64.txt", base64);// define the clip-rectanglepage.clipRect = {top: 0,left: 0,width: width,height: height};// render the imagepage.render(params.outfile);console.log('render complete:' + params.outfile);// exitphantom.exit();});};// get the argsvar params = parseParams();// validate the paramsif (params.options === undefined || params.options.length === 0) {console.log("ERROR: No options or infile found.");usage();phantom.exit();}// set the default out fileif (params.outfile === undefined) {var tmpDir = fs.workingDirectory + '/tmp';// exists tmpDir and is it writable?if (!fs.exists(tmpDir)) {try {fs.makeDirectory(tmpDir);} catch (e) {console.log('ERROR: Cannot make tmp directory');}}params.outfile = tmpDir + "/" + new Date().getTime() + ".png";}// render the imagerender(params);
}());

将上述文件放在项目根目录下的js目录中。

在这里插入图片描述

我们来测试一下是否能生成一个简单的ECharts图表。

创建一个option.json

在这里插入图片描述

首先指定一个option,在官方示例 https://echarts.apache.org/examples/zh/index.html 中,随意找一个柱状图的sample,复制option对象内容到新创建的option.json文件中

{"tooltip": {"trigger": "axis","axisPointer": {"type": "shadow"}},"grid": {"left": "3%","right": "4%","bottom": "3%","containLabel": true},"xAxis": [{"type": "category","data": [ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" ],"axisTick": {"alignWithLabel": true}}],"yAxis": [{"type": "value"}],"series": [{"name": "Direct","type": "bar","barWidth": "60%","data": [ 10, 52, 200, 334, 390, 330, 220 ]}]
}

Program.cs中调用ECharts转换器:

static void Main(string[] args)
{var phantomJS = new PhantomJS();if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)){phantomJS.ToolPath = Path.Combine(basePath, "libs\\phantomjs-2.1.1-windows\\bin");}else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)){phantomJS.ToolPath = Path.Combine(basePath, "libs\\phantomjs-2.1.1-linux-x86_64\\bin");}var scriptPath = Path.Combine(basePath, "js\\echarts-converts.js");var optionPath = Path.Combine(basePath, "js\\option.json");phantomJS.OutputReceived += (sender, e) =>{Console.WriteLine("PhantomJS output: {0}", e.Data);};phantomJS.Run(scriptPath, new string[] { "-infile", optionPath });phantomJS.Abort();}

打印如下

在这里插入图片描述

打开输出路径看到生成的图片。

在这里插入图片描述

生成Word文档

为了方便集成,我加.NET中构件ECharts中可能用的全部数据结构。
这里感谢https://github.com/idoku/EChartsSDK这个项目,代码基本都是从这里拷贝过来的。

这样可以通过指定ChartOption对象,生成图片。

var option = new ChartOption(){title = new List<Title>(){new Title (){text=title, left="center"}},tooltip = new ToolTip(),legend = new Legend(){orient = OrientType.vertical,left = "left"},series = new object[]{new {name= "Access From",type="pie",data=new object[]{new  { value= failedCount, name="异常" },new  { value= passCount, name="正常" },}}}}

根据Document Template Tool图片占位符格式:#字段名称[宽度,高度]#,

在上一章的Sample基础上,在ReportTemplate2.docx中添加图片占位符。

在这里插入图片描述

生成后的文档如下:

在这里插入图片描述

项目地址

库封装

https://github.com/jevonsflash/EChartsGen

本文示例 EChartsGen_DocTemplateTool_Sample

https://github.com/jevonsflash/EChartsGen/tree/master/EChartsGen_DocTemplateTool_Sample

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/194234.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【文件包含】phpmyadmin 文件包含(CVE-2014-8959)

1.1漏洞描述 漏洞编号CVE-2014-8959漏洞类型文件包含漏洞等级高危漏洞环境Windows漏洞名称phpmyadmin 文件包含&#xff08;CVE-2014-8959&#xff09; 描述: phpMyAdmin是一套开源的、基于Web的MySQL数据库管理工具。其index.php中存在一处文件包含逻辑&#xff0c;通过二次编…

多区域OSPF配置

配置命令步骤&#xff1a; 1.使用router ospf 进程ID编号 启用OSPF路由 2.使用network 直连网络地址 反掩码 area 区域号 将其归于对应区域 注意&#xff1a; 1.进程ID编号可任意&#xff08;1-65535&#xff09; 2.反掩码用4个255相减得到 3.area 0 为主干区域 4.连接不…

【Spring】bean的生命周期

这里写目录标题 1. 在类中提供生命周期控制方法&#xff0c;并在配置文件中配置init-method&destroy-method&#xff08;配置&#xff09;关闭容器操作1&#xff1a;ctx.close()关闭容器操作2&#xff1a;关闭钩子&#xff1a;ctx.registerShutdownHook() 2. 实现接口来做和…

MIB 操作系统Lab: Xv6 and Unix utilities(1)boot xv6

从github中下载xv6代码 $ git clone git://g.csail.mit.edu/xv6-labs-2023 $ cd xv6-labs-2023 编译和运行xv6: $ make qemu 如果在终端输入ls命令&#xff0c;能看到输出。 大多数都是可以直接运行的命令。 xv6没有ps命令&#xff0c;但是可以输入ctrl-p可以看到进程的信…

【AI视野·今日NLP 自然语言处理论文速览 第六十五期】Mon, 30 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Mon, 30 Oct 2023 Totally 67 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers An Approach to Automatically generating Riddles aiding Concept Attainment Authors Niharika Sri Parasa,…

单区域OSPF配置

配置命令步骤&#xff1a; 1.使用router ospf 进程ID编号 启用OSPF路由 2.使用network 直连网络地址 反掩码 area 0 将其归于区域0 注意&#xff1a;1.进程ID编号可任意&#xff08;1-65535&#xff09;2.反掩码用4个255相减得到 如下图&#xff0c;根据给出要求配置OSPF单区…

java学习part04

1.进制 计算机底层都是二进制&#xff0c;输出统一十进制 2.算符 3.逻辑算符 4.位运算符 38-变量与运算符-位运算符的使用_哔哩哔哩_bilibili 5.条件运算符

架构师修炼之道

相信大家都对未来的职业发展有着憧憬和规划&#xff0c;要做架构师、要做技术总监、要做CTO。对于如何实现自己的职业规划也都信心满满&#xff0c;努力工作、好好学习、不断提升自己。 相信成为一名优秀的架构师是很多程序员的目标&#xff0c;架构师的工作包罗万象&#xff…

计算机视觉基础(7)——相机基础

前言 从这一节开始&#xff0c;我们来学习几何视觉。中层视觉包括相机模型、单目几何视觉、对极几何视觉和多目立体视觉等。在学习几何视觉最开始&#xff0c;我们先来学习一下相机模型&#xff0c;了解相机的基本原理&#xff0c;了解相机如何记录影像。 一、数字相机 1.1 基…

PVE Win平台虚拟机下如何安装恢复自定义备份Win系统镜像ISO文件(已成功实现)

环境: Virtual Environment 7.3-3 Win s2019 UltraISO9.7 USM6.0 NTLite_v2.1.1.7917 问题描述: PVE Win平台虚拟机下如何安装恢复自定义备份Win系统镜像ISO文件 本次目标 主要是对虚拟机里面Win系统备份做成可安装ISO文件恢复至别的虚拟机或者实体机上 解决方案: …

wpf devexpress项目中添加GridControl绑定数据

本教程讲解了如何添加GridControl到wpf项目中并且绑定数据 原文地址Lesson 1 - Add a GridControl to a Project and Bind it to Data | WPF Controls | DevExpress Documentation 1、使用 DevExpress Template Gallery创建一个新的空白mvvm应用程序&#xff0c;这个项目包括了…

安防监控EasyCVR视频汇聚平台使用海康SDK播放出现花屏是什么原因?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…

【问题处理】WPS提示不能启动此对象的源应用程序如何处理?

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 最近在用WPS打开word文件中&#xff0c;插入的Excel附件时&#xff0c;无法打开&#xff0c;提示&#xff1a;“不能启动此对象的源应用程序”。 经过上网查找处理办法&#xff0c;尝试解决&#xff0c;现将解决过程记…

Linux输入设备应用编程(键盘,触摸屏,按键,鼠标)

目录 一 输入设备编程介绍 1.1 什么是输入设备呢&#xff1f; 1.2 什么是输入设备的应用编程&#xff1f; 1.3 input子系统 1.4 数据读取流程 1.5 应用程序如何解析数据 1.5.1 按键类事件&#xff1a; 1.5.2 相对位移事件 1.5.3 绝对位移事件 二 读取 struct input_e…

C++ 之字符串、字符数组与字符指针(*、**)

C 之字符串、字符数组与字符指针(*、**) 最近频繁使用字符串指针&#xff0c;有时候想取值或者复制&#xff0c;常用到问题&#xff0c;在此总结一下字符串的处理、指针的使用长期更新版~ 1. char 使用相关 1.1 内存使用 首先介绍一下C语言中的数据类型&#xff1a; 下图给…

【文件读取/包含】任意文件读取漏洞 afr_1

1.1漏洞描述 漏洞名称任意文件读取漏洞 afr_1漏洞类型文件读取漏洞等级⭐漏洞环境docker攻击方式 1.2漏洞等级 高危 1.3影响版本 暂无 1.4漏洞复现 1.4.1.基础环境 靶场docker工具BurpSuite 1.4.2.靶场搭建 1.创建docker-compose.yml文件 version: 3.2 services: web: …

服务器数据恢复—磁盘出现坏道掉线导致raid5阵列崩溃的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌服务器中有一组16块SAS接口硬盘组建的raid5磁盘阵列。 服务器故障&检测&#xff1a; 服务器raid5阵列中有2块硬盘掉线&#xff0c;上层服务器应用崩溃&#xff0c;导致服务器数据丢失。丢失的数据主要是4个1.5TB大小的卷中的数据&am…

番外 2 : LoadRunner 的安装以及配置

LoadRunner 的安装以及配置教程 一 . 配置 IE 浏览器二 . 安装 LoadRunner 工具三 . 修改默认浏览器的配置四 . 设置 LoadRunner 能够获取本地资源 Hello , 大家好 , 又给大家带来新的专栏喽 ~ 这个专栏是专门为零基础小白从 0 到 1 了解软件测试基础理论设计的 , 虽然还不足以…

代码随想录算法训练营第五十一天|309. 买卖股票的最佳时机含冷冻期、714. 买卖股票的最佳时机含手续费

第九章 动态规划part12 309. 买卖股票的最佳时机含冷冻期 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&…