java根据模板导出word,并在word中插入echarts相关统计图片以及表格

  • 引入依赖
  • 创建word模板
    • 创建ftl模板文件
    • 保存的ftl可能会出现占位符分割的问题,需要处理
    • 将ftl文件中的图片的Base64删除,并使用占位符代替
    • 插入表格,并指定表格的位置在图片下方
  • Echarts转图片
  • 根据模板生成word文档
    • DocUtil
    • 导出word文档
  • 生成的word统计图片示例
  • 生成的word表格示例

java根据word模板生成对应的word文档,并且要在word文档中插入Echarts的一些统计图表,例如柱状图、折线图、柱状混合图等。思路是根据Echatrs的option生成json文件,然后通过命令行调用phantomjs执行echarts-convert的js脚本生成Echarts对应图表的图片,然后将图片转为Base64的字符串,替换word文档中的图片占位符,实现往word文档中插入统计图表的需求。同时也可以在word中插入表格

引入依赖

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.11</version></dependency><dependency><groupId>com.github.abel533</groupId><artifactId>ECharts</artifactId><version>2.2.7</version></dependency><!-- freemarker engine --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version></dependency>

对应的phantomjs、echarts-convert和ECharts-2.2.7.jar下载地址:phantomjs

创建word模板

创建ftl模板文件

首先使用word创建一个doc文件,其中的主要字段全部用${param}占位符替换,示例如下:
在这里插入图片描述
然后将doc模板另存为xml在这里插入图片描述
重命名为ftl文件。

保存的ftl可能会出现占位符分割的问题,需要处理

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileAppender;
import cn.hutool.core.io.file.FileReader;
import java.util.List;/*** 将分离的占位符去除、变量值重新拼装*/
public class formatXml {public static void main(String[] args) {//文件读取-FileReader//默认UTF-8编码,可以在构造中传入第二个参数作为编码 原始ftl文件FileReader fileReader = new FileReader("C:\\Users\\Desktop\\jijiaritemp11.ftl");//从文件中读取每一行数据List<String> strings = fileReader.readLines();//文件追加-FileAppender//destFile – 目标文件//capacity – 当行数积累多少条时刷入到文件//isNewLineMode – 追加内容是否为新行FileAppender appender = new FileAppender(FileUtil.newFile("C:\\Users\\Desktop\\jiejiaritemp.ftl"), 16, true);//遍历得到每一行数据for (String string : strings) {//判断每一行数据中不包含'$'的数据先添加进新文件if (!string.contains("$")) {appender.append(string);continue;}//如果一行数据中包含'$'变量符将替换为'#$'string = string.replaceAll("\\$", "#\\$");//然后以'#'切割成每一行(数组),这样一来'$'都将在每一行的开头String[] ss = string.split("#");// 同一行的数据写到同一行,文件追加自动换行了(最后的完整数据)StringBuilder sb = new StringBuilder();//遍历每一行(数组ss)for (int i = 0; i < ss.length; i++) {//暂存数据String s1 = ss[i];//将不是以'$'开头的行数据放进StringBuilderif (!s1.startsWith("$")) {sb.append(s1);continue;}//被分离的数据一般都是'${'这样被分开//匹配以'$'开头的变量找到'}' 得到索引位置int i1 = s1.lastIndexOf("}");//先切割得到这个完整体String substr = s1.substring(0, i1 + 1);//把变量追加到StringBuildersb.append(substr.replaceAll("<[^>]+>", ""));//再将标签数据追加到StringBuilder包裹变量sb.append(s1.substring(i1 + 1));}appender.append(sb.toString());}appender.flush();appender.toString();}
}

将ftl文件中的图片的Base64删除,并使用占位符代替

搜索<w:binData标签,删除Base64字符串,使用占位符代替
在这里插入图片描述
注意图片的宽高是模板文件中图片的宽高,如果不修改,最终生成的图片大小会与原始模板中的图片大小保持一致。
在这里插入图片描述

这样,word模板文件ftl就创建好了,只需组装数据即可。

插入表格,并指定表格的位置在图片下方

在这个示例中:
图片通过 <v:shape> 标签插入,其中包含一个 <v:imagedata> 子标签用于指定图片的来源。src=“wordml://03000001.png” 指定了图片的路径或关系 ID。
表格通过 <w:tbl> 标签插入,位于图片的 <w:p> 元素之后。
请注意,src=“wordml://03000001.png” 中的 wordml:// 前缀通常用于指向 Word 文档中嵌入的图片。如果你的图片是作为二进制数据嵌入到 Word 文档中的,你需要确保图片的关系 ID (rId) 与文档中的关系类型 ( 部分) 中定义的 ID 相匹配。
确保图片和表格的 XML 结构按照你希望的顺序排列,这样它们就会按照这个顺序显示在文档中。如果你使用 FreeMarker 或其他模板引擎生成 Word 文档,确保在模板中正确地插入这些标签,并根据需要调整图片和表格的位置。
表格分为表头和数据行,<#list ttFiveWNumList as item>中ttFiveWNumList 为数据集合。

<w:p wsp:rsidR="00CE037D" wsp:rsidRDefault="00CE037D" wsp:rsidP="005E50E9"><w:pPr><w:widowControl/><!-- 居中 --><w:jc w:val="center"/><w:rPr><w:noProof/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312" w:h-ansi="仿宋_GB2312" w:cs="仿宋_GB2312" w:hint="fareast"/><wx:font wx:val="仿宋_GB2312"/><w:sz w:val="32"/><w:sz-cs w:val="32"/></w:rPr><w:t>${holidayName}假期前${num}天五环外公园数据</w:t></w:r></w:p><w:tbl><w:tblPr><w:tblStyle w:val="TableGrid"/><!-- w:type="auto" 使表格宽度自适应内容 --><w:tblW w:type="auto"/><!-- w:jc w:val="center" 设置表格居中显示 --><w:jc w:val="center"/><w:tblBorders><!-- 添加表格框线 设置上边框 --><w:top w:val="single" w:sz="4" w:space="0" w:color="auto"/><!-- 设置下边框 --><w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/><!-- 设置左边框 --><w:left w:val="single" w:sz="4" w:space="0" w:color="auto"/><!-- 设置右边框 --><w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/><!-- 设置内部水平边框 --><w:insideH w:val="single" w:sz="4" w:space="0" w:color="auto"/><!-- 设置内部垂直边框 --><w:insideV w:val="single" w:sz="4" w:space="0" w:color="auto"/></w:tblBorders></w:tblPr><w:tr><w:trPr><w:trHeight w:val="0" w:hRule="auto"/></w:trPr><w:tc><w:tcPr><!-- w:tcW w:type="dxa" w:w="1500" 1500为表格初始列宽,可以调整--><w:tcW w:type="dxa" w:w="1500"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:rPr><w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312" w:h-ansi="仿宋_GB2312" w:cs="仿宋_GB2312" w:hint="fareast"/><w:b w:val="true"/><w:sz w:val="24"/><w:sz-cs w:val="24"/></w:rPr><w:t>天数</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="4000"/></w:tcPr><w:p><w:pPr><!-- 段落内文本居中显示 每一列都需要设置--><w:jc w:val="center"/></w:pPr><w:r><w:rPr><!-- 设置字体样式,大小--><w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312" w:h-ansi="仿宋_GB2312" w:cs="仿宋_GB2312" w:hint="fareast"/><!-- w:b w:val="true"  字体加粗--><w:b w:val="true"/><w:sz w:val="24"/><w:sz-cs w:val="24"/></w:rPr><w:t>${lastYear}年游客量(单位:人次)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:type="dxa" w:w="4000"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:rPr><w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312" w:h-ansi="仿宋_GB2312" w:cs="仿宋_GB2312" w:hint="fareast"/><w:b w:val="true"/><w:sz w:val="24"/><w:sz-cs w:val="24"/></w:rPr><w:t>${currentYear}年游客量(单位:人次)</w:t></w:r></w:p></w:tc></w:tr><#list ttFiveWNumList as item><w:tr><w:tc><w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:rPr><w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312" w:h-ansi="仿宋_GB2312" w:cs="仿宋_GB2312" w:hint="fareast"/><w:sz w:val="20"/><w:sz-cs w:val="20"/></w:rPr><w:t>${item.dayNumber}</w:t></w:r></w:p></w:tc><w:tc><w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:rPr><w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312" w:h-ansi="仿宋_GB2312" w:cs="仿宋_GB2312" w:hint="fareast"/><w:sz w:val="20"/><w:sz-cs w:val="20"/></w:rPr><w:t>${item.totalLastVisitorNumber}</w:t></w:r></w:p></w:tc><w:tc><w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:rPr><w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312" w:h-ansi="仿宋_GB2312" w:cs="仿宋_GB2312" w:hint="fareast"/><w:sz w:val="20"/><w:sz-cs w:val="20"/></w:rPr><w:t>${item.totalVisitorNumber}</w:t></w:r></w:p></w:tc></w:tr></#list></w:tbl>

Echarts转图片


import java.io.*;
import java.math.BigDecimal;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.axis.ValueAxis;
import com.github.abel533.echarts.code.Magic;
import com.github.abel533.echarts.code.Tool;
import com.github.abel533.echarts.code.Trigger;
import com.github.abel533.echarts.feature.MagicType;
import com.github.abel533.echarts.json.GsonOption;
import com.github.abel533.echarts.series.Bar;
import com.github.abel533.echarts.series.Line;
import com.github.abel533.echarts.style.ItemStyle;
import com.github.abel533.echarts.style.itemstyle.Normal;
import com.google.gson.Gson;
import com.hollysmart.admin.modules.project.VO.BusParkVisitorsVO;
import com.hollysmart.admin.modules.project.entity.BusParkVisitors;/*** eachrts后台出图* @author lxd**/
public class EchartsToPicUtil {// echarts包的路径  后面截图有说明private static final String JSpath = "D:\\work\\tourist\\phantomjs\\echarts-convert\\echarts-convert1.js";private static final String ImgPath = "D:\\tourist\\";public static void main(String[] args) {String optiona = "{\"title\":{\"left\":\"center\",\"text\":\"草地植被演替评估\",\"padding\":30,\"textStyle\":{\"fontSize\":18,\"fontWeight\":\"bolder\",\"color\":\"#333\"},\"subtext\":\"2019-03-05 00:00:00-2020-03-04 00:00:00 全部\",\"subtextStyle\":{\"fontSize\":14,\"fontWeight\":\"bold\"}},\"legend\":{\"data\":[\"大柴旦\",\"都兰\",\"兴海\",\"河南\",\"刚察\",\"甘德\",\"杂多\",\"民和\",\"囊谦\",\"五道梁\",\"湟源\",\"久治\",\"同德\",\"湟中\",\"沙珠玉\",\"玉树\",\"乐都\",\"循化\",\"德令哈\",\"乌兰\",\"共和\",\"祁连\",\"治多\",\"贵德\",\"海晏\",\"沱沱河\",\"青海湖151\",\"门源\",\"化隆\",\"泽库\",\"同仁\",\"班玛\",\"格尔木\",\"野牛沟\",\"玛沁\",\"玛多\",\"贵南\",\"大通\",\"茫崖\",\"互助\",\"曲麻莱\",\"小灶火\",\"诺木洪\",\"清水河\",\"西宁\",\"尖扎\",\"冷湖\",\"托勒\",\"达日\",\"天峻\",\"茶卡\",\"平安\"],\"type\":\"scroll\",\"bottom\":10},\"toolbox\":{\"show\":true,\"orient\":\"vertical\",\"y\":\"45%\",\"x\":\"95%\",\"itemSize\":30},\"xAxis\":{\"name\":\"年份\",\"nameLocation\":\"middle\",\"nameTextStyle\":{\"fontSize\":16,\"padding\":15},\"type\":\"category\",\"data\":[\"2019\",\"2020\"],\"splitLine\":{\"show\":false},\"axisLabel\":{\"show\":true,\"textStyle\":{\"fontSize\":14}},\"axisLine\":{\"show\":true,\"onZero\":true,\"lineStyle\":{\"width\":2}},\"axisTick\":{\"show\":\"true\",\"lineStyle\":{\"color\":\"black\",\"width\":2,\"type\":\"solid\"}}},\"yAxis\":[{\"name\":\"结果\",\"nameLocation\":\"middle\",\"nameTextStyle\":{\"fontSize\":16,\"padding\":15},\"type\":\"value\",\"splitLine\":{\"show\":false},\"axisLabel\":{\"fontSize\":14},\"axisLine\":{\"show\":true,\"onZero\":true,\"lineStyle\":{\"width\":2}},\"axisTick\":{\"show\":\"true\",\"lineStyle\":{\"color\":\"black\",\"width\":2,\"type\":\"solid\"}}}],\"grid\":{\"top\":\"10%\",\"bottom\":\"15%\",\"left\":\"10%\",\"right\":\"10%\",\"borderColor\":\"black\",\"borderWidth\":1},\"tooltip\":{\"trigger\":\"axis\",\"axisPointer\":{\"type\":\"none\"}},\"series\":[{\"name\":\"大柴旦\",\"data\":[2306.4,0],\"type\":\"line\"},{\"name\":\"都兰\",\"data\":[2156.8,0],\"type\":\"line\"},{\"name\":\"兴海\",\"data\":[1713.7,0],\"type\":\"line\"},{\"name\":\"河南\",\"data\":[1435.3,0],\"type\":\"line\"},{\"name\":\"刚察\",\"data\":[1523,0],\"type\":\"line\"},{\"name\":\"甘德\",\"data\":[1131.1,0],\"type\":\"line\"},{\"name\":\"杂多\",\"data\":[1524.6,0],\"type\":\"line\"},{\"name\":\"民和\",\"data\":[3595.1,0],\"type\":\"line\"},{\"name\":\"囊谦\",\"data\":[2331.7,0],\"type\":\"line\"},{\"name\":\"五道梁\",\"data\":[599.6,0],\"type\":\"line\"},{\"name\":\"湟源\",\"data\":[2328,0],\"type\":\"line\"},{\"name\":\"久治\",\"data\":[1583.5,0],\"type\":\"line\"},{\"name\":\"同德\",\"data\":[1990.1,0],\"type\":\"line\"},{\"name\":\"湟中\",\"data\":[2384.8,0],\"type\":\"line\"},{\"name\":\"沙珠玉\",\"data\":[2119.9,0],\"type\":\"line\"},{\"name\":\"玉树\",\"data\":[1862.3,0],\"type\":\"line\"},{\"name\":\"乐都\",\"data\":[3312.2,0],\"type\":\"line\"},{\"name\":\"循化\",\"data\":[3727.7,0],\"type\":\"line\"},{\"name\":\"德令哈\",\"data\":[2522.5,0],\"type\":\"line\"},{\"name\":\"乌兰\",\"data\":[2402.6,0],\"type\":\"line\"},{\"name\":\"共和\",\"data\":[2461.3,0],\"type\":\"line\"},{\"name\":\"祁连\",\"data\":[1993.3,0],\"type\":\"line\"},{\"name\":\"治多\",\"data\":[1258.9,0],\"type\":\"line\"},{\"name\":\"贵德\",\"data\":[3421.9,0],\"type\":\"line\"},{\"name\":\"海晏\",\"data\":[1770.8,0],\"type\":\"line\"},{\"name\":\"沱沱河\",\"data\":[922.2,0],\"type\":\"line\"},{\"name\":\"青海湖151\",\"data\":[1822.5,0],\"type\":\"line\"},{\"name\":\"门源\",\"data\":[1903,0],\"type\":\"line\"},{\"name\":\"化隆\",\"data\":[2041.8,0],\"type\":\"line\"},{\"name\":\"泽库\",\"data\":[1227.2,0],\"type\":\"line\"},{\"name\":\"同仁\",\"data\":[2892.2,0],\"type\":\"line\"},{\"name\":\"班玛\",\"data\":[1921.5,0],\"type\":\"line\"},{\"name\":\"格尔木\",\"data\":[2918.8,0],\"type\":\"line\"},{\"name\":\"野牛沟\",\"data\":[1197.6,0],\"type\":\"line\"},{\"name\":\"玛沁\",\"data\":[1407,0],\"type\":\"line\"},{\"name\":\"玛多\",\"data\":[893.3,0],\"type\":\"line\"},{\"name\":\"贵南\",\"data\":[1954.2,0],\"type\":\"line\"},{\"name\":\"大通\",\"data\":[2451.6,0],\"type\":\"line\"},{\"name\":\"茫崖\",\"data\":[2480.6,0],\"type\":\"line\"},{\"name\":\"互助\",\"data\":[2454.6,0],\"type\":\"line\"},{\"name\":\"曲麻莱\",\"data\":[1131.7,0],\"type\":\"line\"},{\"name\":\"小灶火\",\"data\":[2666.8,0],\"type\":\"line\"},{\"name\":\"诺木洪\",\"data\":[2876.4,0],\"type\":\"line\"},{\"name\":\"清水河\",\"data\":[805.9,0],\"type\":\"line\"},{\"name\":\"西宁\",\"data\":[2767.6,0],\"type\":\"line\"},{\"name\":\"尖扎\",\"data\":[3422.2,0],\"type\":\"line\"},{\"name\":\"冷湖\",\"data\":[2497,0],\"type\":\"line\"},{\"name\":\"托勒\",\"data\":[1366.5,0],\"type\":\"line\"},{\"name\":\"达日\",\"data\":[1329,0],\"type\":\"line\"},{\"name\":\"天峻\",\"data\":[1400.1,0],\"type\":\"line\"},{\"name\":\"茶卡\",\"data\":[2120.6,0],\"type\":\"line\"},{\"name\":\"平安\",\"data\":[3214.8,0],\"type\":\"line\"}]}";//前端传的option数据// generateEChart(optiona, "D:/",JSpath);//后台构造的柱状图数据
//		 generateEChart(testBar(true), "D:/",JSpath);//后台构造的折线图数据generateEChart(testLine(true), ImgPath,JSpath);}public static String echartsToBase64(String type){String optiona = "{\"title\":{\"left\":\"center\",\"text\":\"草地植被演替评估\",\"padding\":30,\"textStyle\":{\"fontSize\":18,\"fontWeight\":\"bolder\",\"color\":\"#333\"},\"subtext\":\"2019-03-05 00:00:00-2020-03-04 00:00:00 全部\",\"subtextStyle\":{\"fontSize\":14,\"fontWeight\":\"bold\"}},\"legend\":{\"data\":[\"大柴旦\",\"都兰\",\"兴海\",\"河南\",\"刚察\",\"甘德\",\"杂多\",\"民和\",\"囊谦\",\"五道梁\",\"湟源\",\"久治\",\"同德\",\"湟中\",\"沙珠玉\",\"玉树\",\"乐都\",\"循化\",\"德令哈\",\"乌兰\",\"共和\",\"祁连\",\"治多\",\"贵德\",\"海晏\",\"沱沱河\",\"青海湖151\",\"门源\",\"化隆\",\"泽库\",\"同仁\",\"班玛\",\"格尔木\",\"野牛沟\",\"玛沁\",\"玛多\",\"贵南\",\"大通\",\"茫崖\",\"互助\",\"曲麻莱\",\"小灶火\",\"诺木洪\",\"清水河\",\"西宁\",\"尖扎\",\"冷湖\",\"托勒\",\"达日\",\"天峻\",\"茶卡\",\"平安\"],\"type\":\"scroll\",\"bottom\":10},\"toolbox\":{\"show\":true,\"orient\":\"vertical\",\"y\":\"45%\",\"x\":\"95%\",\"itemSize\":30},\"xAxis\":{\"name\":\"年份\",\"nameLocation\":\"middle\",\"nameTextStyle\":{\"fontSize\":16,\"padding\":15},\"type\":\"category\",\"data\":[\"2019\",\"2020\"],\"splitLine\":{\"show\":false},\"axisLabel\":{\"show\":true,\"textStyle\":{\"fontSize\":14}},\"axisLine\":{\"show\":true,\"onZero\":true,\"lineStyle\":{\"width\":2}},\"axisTick\":{\"show\":\"true\",\"lineStyle\":{\"color\":\"black\",\"width\":2,\"type\":\"solid\"}}},\"yAxis\":[{\"name\":\"结果\",\"nameLocation\":\"middle\",\"nameTextStyle\":{\"fontSize\":16,\"padding\":15},\"type\":\"value\",\"splitLine\":{\"show\":false},\"axisLabel\":{\"fontSize\":14},\"axisLine\":{\"show\":true,\"onZero\":true,\"lineStyle\":{\"width\":2}},\"axisTick\":{\"show\":\"true\",\"lineStyle\":{\"color\":\"black\",\"width\":2,\"type\":\"solid\"}}}],\"grid\":{\"top\":\"10%\",\"bottom\":\"15%\",\"left\":\"10%\",\"right\":\"10%\",\"borderColor\":\"black\",\"borderWidth\":1},\"tooltip\":{\"trigger\":\"axis\",\"axisPointer\":{\"type\":\"none\"}},\"series\":[{\"name\":\"大柴旦\",\"data\":[2306.4,0],\"type\":\"line\"},{\"name\":\"都兰\",\"data\":[2156.8,0],\"type\":\"line\"},{\"name\":\"兴海\",\"data\":[1713.7,0],\"type\":\"line\"},{\"name\":\"河南\",\"data\":[1435.3,0],\"type\":\"line\"},{\"name\":\"刚察\",\"data\":[1523,0],\"type\":\"line\"},{\"name\":\"甘德\",\"data\":[1131.1,0],\"type\":\"line\"},{\"name\":\"杂多\",\"data\":[1524.6,0],\"type\":\"line\"},{\"name\":\"民和\",\"data\":[3595.1,0],\"type\":\"line\"},{\"name\":\"囊谦\",\"data\":[2331.7,0],\"type\":\"line\"},{\"name\":\"五道梁\",\"data\":[599.6,0],\"type\":\"line\"},{\"name\":\"湟源\",\"data\":[2328,0],\"type\":\"line\"},{\"name\":\"久治\",\"data\":[1583.5,0],\"type\":\"line\"},{\"name\":\"同德\",\"data\":[1990.1,0],\"type\":\"line\"},{\"name\":\"湟中\",\"data\":[2384.8,0],\"type\":\"line\"},{\"name\":\"沙珠玉\",\"data\":[2119.9,0],\"type\":\"line\"},{\"name\":\"玉树\",\"data\":[1862.3,0],\"type\":\"line\"},{\"name\":\"乐都\",\"data\":[3312.2,0],\"type\":\"line\"},{\"name\":\"循化\",\"data\":[3727.7,0],\"type\":\"line\"},{\"name\":\"德令哈\",\"data\":[2522.5,0],\"type\":\"line\"},{\"name\":\"乌兰\",\"data\":[2402.6,0],\"type\":\"line\"},{\"name\":\"共和\",\"data\":[2461.3,0],\"type\":\"line\"},{\"name\":\"祁连\",\"data\":[1993.3,0],\"type\":\"line\"},{\"name\":\"治多\",\"data\":[1258.9,0],\"type\":\"line\"},{\"name\":\"贵德\",\"data\":[3421.9,0],\"type\":\"line\"},{\"name\":\"海晏\",\"data\":[1770.8,0],\"type\":\"line\"},{\"name\":\"沱沱河\",\"data\":[922.2,0],\"type\":\"line\"},{\"name\":\"青海湖151\",\"data\":[1822.5,0],\"type\":\"line\"},{\"name\":\"门源\",\"data\":[1903,0],\"type\":\"line\"},{\"name\":\"化隆\",\"data\":[2041.8,0],\"type\":\"line\"},{\"name\":\"泽库\",\"data\":[1227.2,0],\"type\":\"line\"},{\"name\":\"同仁\",\"data\":[2892.2,0],\"type\":\"line\"},{\"name\":\"班玛\",\"data\":[1921.5,0],\"type\":\"line\"},{\"name\":\"格尔木\",\"data\":[2918.8,0],\"type\":\"line\"},{\"name\":\"野牛沟\",\"data\":[1197.6,0],\"type\":\"line\"},{\"name\":\"玛沁\",\"data\":[1407,0],\"type\":\"line\"},{\"name\":\"玛多\",\"data\":[893.3,0],\"type\":\"line\"},{\"name\":\"贵南\",\"data\":[1954.2,0],\"type\":\"line\"},{\"name\":\"大通\",\"data\":[2451.6,0],\"type\":\"line\"},{\"name\":\"茫崖\",\"data\":[2480.6,0],\"type\":\"line\"},{\"name\":\"互助\",\"data\":[2454.6,0],\"type\":\"line\"},{\"name\":\"曲麻莱\",\"data\":[1131.7,0],\"type\":\"line\"},{\"name\":\"小灶火\",\"data\":[2666.8,0],\"type\":\"line\"},{\"name\":\"诺木洪\",\"data\":[2876.4,0],\"type\":\"line\"},{\"name\":\"清水河\",\"data\":[805.9,0],\"type\":\"line\"},{\"name\":\"西宁\",\"data\":[2767.6,0],\"type\":\"line\"},{\"name\":\"尖扎\",\"data\":[3422.2,0],\"type\":\"line\"},{\"name\":\"冷湖\",\"data\":[2497,0],\"type\":\"line\"},{\"name\":\"托勒\",\"data\":[1366.5,0],\"type\":\"line\"},{\"name\":\"达日\",\"data\":[1329,0],\"type\":\"line\"},{\"name\":\"天峻\",\"data\":[1400.1,0],\"type\":\"line\"},{\"name\":\"茶卡\",\"data\":[2120.6,0],\"type\":\"line\"},{\"name\":\"平安\",\"data\":[3214.8,0],\"type\":\"line\"}]}";//前端传的option数据// generateEChart(optiona, "D:/",JSpath);switch (type) {case "1":optiona = "{\n" +"  title: {\n" +"    text: '假期第2天全市公园游客量、收入额对比图',\n" +"    left: 'center' // 水平居中\n" +"  },\n" +"  tooltip: {\n" +"    trigger: 'axis'\n" +"  },\n" +"  legend: {\n" +"    data: ['游客量(万人)', '收入额(万元)'],\n" +"    top: '5%'\n" +"  },\n" +"  toolbox: {\n" +"    show: true,\n" +"    feature: {\n" +"      dataView: { show: true, readOnly: false },\n" +"      magicType: { show: true, type: ['line', 'bar'] },\n" +"      restore: { show: true },\n" +"      saveAsImage: { show: true }\n" +"    }\n" +"  },\n" +"  calculable: true,\n" +"  xAxis: [\n" +"    {\n" +"      type: 'category',\n" +"      // prettier-ignore\n" +"      data: ['2024年', '2025年']\n" +"    }\n" +"  ],\n" +"  yAxis: [\n" +"    {\n" +"      type: 'value'\n" +"    }\n" +"  ],\n" +"  series: [\n" +"    {\n" +"      name: '游客量(万人)',\n" +"      type: 'bar',\n" +"      data: [\n" +"        169.90, 159.29\n" +"      ],\n" +"      markPoint: {\n" +"        data: [\n" +"          { type: 'max', name: 'Max' },\n" +"          { type: 'min', name: 'Min' }\n" +"        ]\n" +"      }\n" +"    },\n" +"    {\n" +"      name: '收入额(万元)',\n" +"      type: 'bar',\n" +"      data: [\n" +"        2622.30, 2012.14\n" +"      ],\n" +"      markPoint: {\n" +"        data: [\n" +"          { type: 'max', name: 'Max' },\n" +"          { type: 'min', name: 'Min' }\n" +"        ]\n" +"      }\n" +"    }\n" +"  ]\n" +"}";return generateEChart(testBar(true), ImgPath,JSpath);case "2":return generateEChart(testLine(true), ImgPath,JSpath);case "3":return generateEChart(optiona, ImgPath,JSpath);default:return generateEChart(testBar(true), ImgPath,JSpath);}}public static String generateFive(String num,String currentYear,String lastYear,List<BusParkVisitorsVO> visitors) {String optiona = "{\n" +"  title: {\n" +"    text: '假期前"+ num +"天全市五环外公园游客量对比图', // 设置标题文本\n" +"    left: 'center', // 水平居中\n" +"    top: 'top', // 可以根据需要调整标题的垂直位置,'top' 表示顶部\n" +"  },\n" +"  tooltip: {\n" +"    trigger: 'axis',\n" +"    axisPointer: {\n" +"      type: 'cross',\n" +"      crossStyle: {\n" +"        color: '#999'\n" +"      }\n" +"    }\n" +"  },\n" +"  toolbox: {\n" +"    feature: {\n" +"      dataView: { show: true, readOnly: false },\n" +"      magicType: { show: true, type: ['line', 'bar'] },\n" +"      restore: { show: true },\n" +"      saveAsImage: { show: true }\n" +"    }\n" +"  },\n" +"  legend: {\n" +"    data: ['"+lastYear+"年五环外公园游客量', '"+currentYear+"年五环外公园游客量', '日环比','同比'],\n" +"    top: '4%'\n" +"  },\n" +"  grid: {\n" +"    left: '7%',\n" +"    right: '2%',\n" +"    bottom: '2%',\n" +"    top: '15%',\n" +"    containLabel: true\n" +"  },\n" +"  xAxis: [\n" +"    {\n" +"      type: 'category',\n" +"      data: ["+visitors.stream().map(o -> "'" + o.getDayNumber() + "'").collect(Collectors.joining(","))+"],\n" +"      axisPointer: {\n" +"        type: 'shadow'\n" +"      }\n" +"    }\n" +"  ],\n" +"  yAxis: [\n" +"    {\n" +"      type: 'value',\n" +"      name: '五环外公园游客量(万人)',\n" +"      interval: 50,\n" +"      axisLabel: {\n" +"        formatter: '{value} '\n" +"      }\n" +"    },\n" +"    {\n" +"      type: 'value',\n" +"      name: '日环比(%)',\n" +"      interval: 10,\n" +"      axisLabel: {\n" +"        formatter: '{value} '\n" +"      }\n" +"    }\n" +"  ],\n" +"  series: [\n" +"    {\n" +"      name: '"+lastYear+"年五环外公园游客量',\n" +"      type: 'bar',\n" +"      tooltip: {\n" +"        valueFormatter: function (value) {\n" +"          return value + ' 游客量(万人)';\n" +"        }\n" +"      },\n" +"      data: ["+visitors.stream().map(o -> "'" + (o.getTotalLastVisitorNum()) + "'").collect(Collectors.joining(","))+"],\n" +"		itemStyle: {\n" +"        color: '#4E68B8' // 指定柱状图颜色\n" +"      },\n"+"      label: {\n" +"        show: true, // 显示标签\n" +"        position: 'top' // 标签位置在柱状图的顶部\n" +"        // formatter: '{value} 万人次' // 格式化标签内容\n" +"      }\n" +"    },\n" +"    {\n" +"      name: '"+currentYear+"年五环外公园游客量',\n" +"      type: 'bar',\n" +"      tooltip: {\n" +"        valueFormatter: function (value) {\n" +"          return value + ' 游客量(万人)';\n" +"        }\n" +"      },\n" +"      data: ["+visitors.stream().map(o -> "'" + o.getTotalVisitorNum() + "'").collect(Collectors.joining(","))+"],\n" +"		itemStyle: {\n" +"        color: '#91CC75' // 指定柱状图颜色\n" +"      },\n"+"      label: {\n" +"        show: true, // 显示标签\n" +"        position: 'top' // 标签位置在柱状图的顶部\n" +"        // formatter: '{value} 万人次' // 格式化标签内容\n" +"      }\n" +"    },\n" +"    {\n" +"      name: '日环比',\n" +"      type: 'line',\n" +"      yAxisIndex: 1,\n" +"      tooltip: {\n" +"        valueFormatter: function (value) {\n" +"          return value + ' %';\n" +"        }\n" +"      },\n" +"      data: ["+visitors.stream().map(o -> "'" + o.getChain() + "'").collect(Collectors.joining(","))+"],\n" +"		itemStyle: {\n" +"        color: '#D6C029' // 指定柱状图颜色\n" +"      },\n"+"      label: {\n" +"        show: true, // 显示标签\n" +"        position: 'top' // 标签位置在柱状图的顶部\n" +"        // formatter: '{value} 万人次' // 格式化标签内容\n" +"      }\n" +"    },\n" +"    {\n" +"      name: '同比',\n" +"      type: 'line',\n" +"      yAxisIndex: 1,\n" +"      tooltip: {\n" +"        valueFormatter: function (value) {\n" +"          return value + ' %';\n" +"        }\n" +"      },\n" +"      data: ["+visitors.stream().map(o -> "'" + o.getYearOnYear() + "'").collect(Collectors.joining(","))+"],\n" +"		itemStyle: {\n" +"        color: '#F81D43' // 指定柱状图颜色\n" +"      },\n"+"      label: {\n" +"        show: true, // 显示标签\n" +"        position: 'top' // 标签位置在柱状图的顶部\n" +"        // formatter: '{value} 万人次' // 格式化标签内容\n" +"      }\n" +"    }\n" +"  ]\n" +"}";return  generateEChart(optiona, ImgPath,JSpath);}public static String generateEChart(String options, String tmpPath,String echartJsPath) {String dataPath = writeFile(options,tmpPath);String fileName =  UUID.randomUUID().toString().substring(0, 8) + ".png";String path = tmpPath + fileName;String base64Str = "";try {File file = new File(path); // 文件路径(路径+文件名)if (!file.exists()) { // 文件不存在则创建文件,先创建目录File dir = new File(file.getParent());dir.mkdirs();file.createNewFile();}String cmd = "D:\\work\\tourist\\phantomjs\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe  " + echartJsPath + " -infile " + dataPath+ " -outfile " + path;// 使用
//			Process process = Runtime.getRuntime().exec(cmd);// 创建 ProcessBuilder 对象ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", cmd);builder.redirectErrorStream(true); // 将错误输出重定向到标准输出// 启动进程Process process = builder.start();BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));String line = "";while ((line = input.readLine()) != null) {System.out.println(line);}input.close();base64Str = encodeFileToBase64Binary(path);File jsonFile=new File(path);if(jsonFile.exists()){jsonFile.delete();}File jsFile=new File(dataPath);if(jsFile.exists()){jsFile.delete();}} catch (IOException e) {e.printStackTrace();} finally {return base64Str;}}public static String writeFile(String options,String tmpPath) {String dataPath = tmpPath+ UUID.randomUUID().toString().substring(0, 8) + ".json";try {/* 写入Txt文件 使用UFT-8编码*/String encoding = "UTF-8";File writename = new File(dataPath); // 相对路径,如果没有则要建立一个新的output.txt文件if (!writename.exists()) { // 文件不存在则创建文件,先创建目录File dir = new File(writename.getParent());dir.mkdirs();writename.createNewFile(); // 创建新文件}FileOutputStream fos = new FileOutputStream(writename);OutputStreamWriter osw = new OutputStreamWriter(fos, encoding);osw.write(options);osw.flush();osw.close();
//			BufferedWriter out = new BufferedWriter(new FileWriter(writename));
//			out.write(options); // \r\n即为换行
//			out.flush(); // 把缓存区内容压入文件
//			out.close(); // 最后记得关闭文件} catch (IOException e) {e.printStackTrace();}return dataPath;}/*** 折线图* * @param isHorizontal*            是否水平放置*/public static String testLine(boolean isHorizontal) {String[] types = { "邮件营销", "联盟广告", "视频广告" };int[][] datas = { { 120, 132, 101, 134, 90, 230, 210 },{ 220, 182, 191, 234, 290, 330, 310 },{ 150, 232, 201, 154, 190, 330, 410 } };String title = "广告数据";GsonOption option = new GsonOption();option.title().text(title).subtext("虚构").x("left");// 大标题、小标题、位置// 提示工具option.tooltip().trigger(Trigger.axis);// 在轴上触发提示数据// 工具栏option.toolbox().show(true).feature(Tool.saveAsImage);// 显示保存为图片option.legend(types);// 图例CategoryAxis category = new CategoryAxis();// 轴分类category.data("周一", "周二", "周三", "周四", "周五", "周六", "周日");category.boundaryGap(false);// 起始和结束两端空白策略// 循环数据for (int i = 0; i < types.length; i++) {Line line = new Line();// 三条线,三个对象String type = types[i];line.name(type).stack("总量");for (int j = 0; j < datas[i].length; j++)line.data(datas[i][j]);option.series(line);}if (isHorizontal) {// 横轴为类别、纵轴为值option.xAxis(category);// x轴option.yAxis(new ValueAxis());// y轴} else {// 横轴为值、纵轴为类别option.xAxis(new ValueAxis());// x轴option.yAxis(category);// y轴}return new Gson().toJson(option);}/*** 柱状图* * @param isHorizontal*            是否水平放置*/public static String testBar(boolean isHorizontal) {String[] citis = { "广州", "深圳", "珠海", "汕头", "韶关", "佛山" };int[] datas = { 6030, 7800, 5200, 3444, 2666, 5708 };String[] colors = { "rgb(2,111,230)", "rgb(186,73,46)","rgb(78,154,97)", "rgb(2,111,230)", "rgb(186,73,46)","rgb(78,154,97)" };String title = "地市数据";GsonOption option = new GsonOption();option.title(title); // 标题// 工具栏option.toolbox().show(true).feature(Tool.mark, // 辅助线Tool.dataView, // 数据视图new MagicType(Magic.line, Magic.bar),// 线图、柱状图切换Tool.restore,// 还原Tool.saveAsImage);// 保存为图片option.tooltip().show(true).formatter("{a} <br/>{b} : {c}");// 显示工具提示,设置提示格式option.legend(title);// 图例Bar bar = new Bar(title);// 图类别(柱状图)CategoryAxis category = new CategoryAxis();// 轴分类category.data(citis);// 轴数据类别// 循环数据for (int i = 0; i < citis.length; i++) {int data = datas[i];String color = colors[i];// 类目对应的柱状图HashMap<String, Object> map = new HashMap<String, Object>(2);map.put("value", data);map.put("itemStyle",new ItemStyle().normal(new Normal().color(color)));bar.data(map);}if (isHorizontal) {// 横轴为类别、纵轴为值option.xAxis(category);// x轴option.yAxis(new ValueAxis());// y轴} else {// 横轴为值、纵轴为类别option.xAxis(new ValueAxis());// x轴option.yAxis(category);// y轴}option.series(bar);return new Gson().toJson(option);}public static String encodeFileToBase64Binary(String fileName) throws IOException {File file = new File(fileName);FileInputStream fileInputStreamReader = new FileInputStream(file);byte[] bytes = new byte[(int) file.length()];fileInputStreamReader.read(bytes);// 使用 Base64 编码器将字节数组编码为 Base64 字符串String encodedfile = Base64.getEncoder().encodeToString(bytes);fileInputStreamReader.close();
//		System.out.println("base64Image:" + encodedfile);return encodedfile;}public static String formatNum(Long num) {// 格式化数字,以万为单位,保留两位小数String formatNumStr = String.format("%.2f", num / 10000.0);return formatNumStr;}public static String formatNum(BigDecimal num) {// 格式化数字,以万为单位,保留两位小数String formatNumStr = String.format("%.2f", num.doubleValue() / 10000.0);return formatNumStr;}}

这里需要替换JSpath为echarts-convert1.js的路径、phantomjs.exe的路径。
对于echarts的optiona,可以先在 echarts官网上找到对应的统计图表,然后调整好样式后复制到代码中,主要参数需要替换为真实数据。

根据模板生成word文档

DocUtil

import freemarker.template.*;import java.io.*;
import java.util.*;public class DocUtil {public Configuration configure=null;public DocUtil(){configure=new Configuration(Configuration.VERSION_2_3_22);configure.setDefaultEncoding("utf-8");}/*** 根据Doc模板生成word文件* @param dataMap 需要填入模板的数据* @param downloadType 文件名称* @param savePath 保存路径*/public void createDoc(Map<String,Object> dataMap, String downloadType, String savePath){try {//加载需要装填的模板Template template=null;//设置模板装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载。//加载模板文件Configuration configuration = new Configuration();configuration.setDirectoryForTemplateLoading(FileUtils.getClassPathTemplatesFile("/excels/"));configuration.setObjectWrapper(new DefaultObjectWrapper());configuration.setDefaultEncoding("UTF-8"); //这个一定要设置,不然在生成的页面中 会乱码//            configure.setClassForTemplateLoading(this.getClass(), "/excels/");//设置对象包装器
//            configure.setObjectWrapper(new DefaultObjectWrapper());//设置异常处理器configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);//定义Template对象,注意模板类型名字与downloadType要一致
//            template = configuration.getTemplate("/"+downloadType+".ftl");try {template = configuration.getTemplate("/"+downloadType+".ftl");} catch (IOException e) {throw new RuntimeException("模板文件不存在: " + downloadType + ".ftl", e);}File outFile=new File(savePath);// 文件已存在,删除原文件if(outFile.exists()){outFile.delete();}Writer out=null;out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));template.process(dataMap, out);out.close();} catch (IOException  e) {e.printStackTrace();} catch (TemplateException e) {e.printStackTrace();}}public String getImageStr(String imgFile){InputStream in=null;byte[] data=null;try {in=new FileInputStream(imgFile);data=new byte[in.available()];in.read(data);in.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}
//        BASE64Encoder encoder=new BASE64Encoder();
//        return encoder.encode(data);String encodedString = Base64.getEncoder().encodeToString(data);return encodedString;}
}

导出word文档

/*** 导出统计word报告* @param firstDate * @param LastFirstDate * @return*/@RequestMapping(value = "exportWord1", method = RequestMethod.GET)public ResponseResult exportWord1(@RequestParam("firstDate") String firstDate,@RequestParam("LastFirstDate") String LastFirstDate){DocUtil docUtil=new DocUtil();Map<String, Object> dataMap=new HashMap<String, Object>();String WordTemplate = "";try{WordTemplate = "jiejiaritemp";// 格式化今天的日期为MM月dd日LocalDate localDate = LocalDate.now();String currentDate = localDate.toString();String[] currentDateArr = currentDate.split("-");String currentDateStr = currentDateArr[1] + "月" + currentDateArr[2] + "日";String currentDateStr1 = currentDateArr[0] + "-" + currentDateArr[1] + "-" + currentDateArr[2];// 计算firstDate与currentDate的差值int days = DateUtils.daysBetween(DateUtils.parseDate(firstDate), DateUtils.parseDate(currentDate));int days1 = days + 1;// 循环生成每一天的数据dataMap.put("currentDate", currentDateStr);dataMap.put("holidayName", "春节");dataMap.put("num", days1);// 组装数据List<BusParkVisitorsVO> list3 = busParkVisitorsService.selectFiveTourists(firstDate,currentDateStr1,null,"五环外");List<BusParkVisitorsVO> list4 = busParkVisitorsService.selectFiveTourists(LastFirstDate,lastDate,null,"五环外");// 将list3转为map,key为dayNumber,value为VisitorsListVOMap<Integer, List<BusParkVisitorsVO>> map3 = list3.stream().collect(Collectors.groupingBy(BusParkVisitorsVO::getSort));Map<Integer, List<BusParkVisitorsVO>> map4 = list4.stream().collect(Collectors.groupingBy(BusParkVisitorsVO::getSort));List<BusParkVisitorsVO> list5 = new ArrayList<>();// 计算同比与日环比for (Integer sort : map3.keySet()) {List<BusParkVisitorsVO> visitorsListVOList3 = map3.get(sort);List<BusParkVisitorsVO> visitorsListVOList4 = map4.get(sort);BusParkVisitorsVO busParkVisitorsVO = visitorsListVOList3.get(0);if (visitorsListVOList3.size() == 0 || visitorsListVOList4.size() == 0) {continue;}double dayNumberPc = calculatePercentageChange((long) visitorsListVOList3.get(0).getFdVisitorNumber(), (long) visitorsListVOList4.get(0).getFdVisitorNumber());double dayNumberR;if(sort==1){dayNumberR = 0;}else{dayNumberR = calculatePercentageChange((long) visitorsListVOList3.get(0).getFdVisitorNumber(), (long) map3.get(sort-1).get(0).getFdVisitorNumber());}busParkVisitorsVO.setTotalVisitorNum(formatNum((long) visitorsListVOList3.get(0).getFdVisitorNumber()));busParkVisitorsVO.setTotalLastVisitorNum(formatNum((long) visitorsListVOList4.get(0).getFdVisitorNumber()));busParkVisitorsVO.setYearOnYear(dayNumberPc);busParkVisitorsVO.setChain(dayNumberR);list5.add(busParkVisitorsVO);}String pic5Base64Img = EchartsToPicUtil.generateFive(String.valueOf(days1),currentDateArr[0],lastDate.split("-")[0],list5);dataMap.put("pic5", pic5Base64Img);dataMap.put("currentDateTime", currentDateArr[0] + "年" +currentDateArr[1] + "月" + currentDateArr[2] + "日");String savedDir = System.getProperty("resources"); //获取服务器指定文件存取路径String dir = savedDir + "/touristStatistics/";File file2 = new File(dir);    //创建文件夹 如果不存在if (!file2.exists()) {file2.mkdirs();}String fileName = currentDateArr[0] + "年" +currentDateArr[1] + "月" + currentDateArr[2] + "日" + "全市游人量统计报告.doc";docUtil.createDoc(dataMap, WordTemplate,  dir+"/"+fileName);fileName = "/touristStatistics/" + fileName;return ResponseResult.ok(fileName);}catch (Exception ex){ex.printStackTrace();return ResponseResult.build(500,"生成word失敗,"+ex.toString());}}

在这里插入图片描述

生成的word统计图片示例

在这里插入图片描述

生成的word表格示例

在这里插入图片描述

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

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

相关文章

RabbitMQ的工作模式

&#xff08;一&#xff09;工作模式 RabbitMQ有7种工作模式来进行消息传递&#xff0c;我们上一篇博客就是简单模式 1.简单模式&#xff08;simple&#xff09; 也就是点对点的形式 P就是生产者&#xff0c;C就是消费者&#xff0c;Queue就是消息队列&#xff08;生产者向qu…

晨辉面试抽签和评分管理系统之十:如何搭建自己的数据库服务器,使用本软件的网络版

晨辉面试抽签和评分管理系统&#xff08;下载地址:www.chenhuisoft.cn&#xff09;是公务员招录面试、教师资格考试面试、企业招录面试等各类面试通用的考生编排、考生入场抽签、候考室倒计时管理、面试考官抽签、面试评分记录和成绩核算的面试全流程信息化管理软件。提供了考生…

迅为RK3568开发板篇OpenHarmony配置HDF驱动控制LED-新增 topeet子系统-编写 bundle.json文件

bundle.json 文件内容如下所示&#xff1a; 下面是对各个字段的解释&#xff1a; 1. name: "ohos/demos" - 这是组件或项目的名称&#xff0c;这里表示它属于 OHOS&#xff08;OpenHarmony OS&#xff09;生态系统下的一个名为"demos"的组件。 2. descri…

JavaScript-正则表达式方法(RegExp)

RegExp 对象用于将文本与一个模式匹配。 有两种方法可以创建一个 RegExp 对象&#xff1a;一种是字面量&#xff0c;另一种是构造函数。 字面量由斜杠 (/) 包围而不是引号包围。 构造函数的字符串参数由引号而不是斜杠包围。 new RegExp(pattern[, flags])一.符集合 1.选择…

信凯科技业绩波动明显:毛利率远弱行业,资产负债率偏高

《港湾商业观察》施子夫 1月8日&#xff0c;深交所官网显示&#xff0c;浙江信凯科技集团股份有限公司&#xff08;以下简称“信凯科技”&#xff09;主板IPO提交注册。 自2022年递交上市申请&#xff0c;信凯科技的IPO之路已走过两年光景&#xff0c;尽管提交注册&#xff0…

Windows远程桌面网关出现重大漏洞

微软披露了其Windows远程桌面网关&#xff08;RD Gateway&#xff09;中的一个重大漏洞&#xff0c;该漏洞可能允许攻击者利用竞争条件&#xff0c;导致拒绝服务&#xff08;DoS&#xff09;攻击。该漏洞被标识为CVE-2025-21225&#xff0c;已在2025年1月的补丁星期二更新中得到…

4G DTU赋能智能配电环网柜通信运维管理

在智能电网建设持续推进下&#xff0c;智能配电环网柜作为配电网的关键节点设备&#xff0c;其稳定、高效运行对保障电力可靠供应是品质生活的基本保障。通信系统是实现智能配电环网柜远程监控与管理的核心纽带&#xff0c;而4G DTU&#xff08;数据传输单元&#xff09;凭借其…

STC的51单片机LED点灯基于KEIL

前言&#xff1a; 该文源于回答一个朋友的问题&#xff0c;代码为该朋友上传&#xff0c;略作修改&#xff0c;在此说明问题以及解决问题的思路&#xff0c;以减少新手错误。 电路图&#xff1a; 该位朋友未上传电路图&#xff0c;说明如下&#xff1a; stc8g1k08a-sop8控制…

C++ 文字识别OCR

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…

基于springboot的自习室预订系统

作者&#xff1a;学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等 文末获取“源码数据库万字文档PPT”&#xff0c;支持远程部署调试、运行安装。 项目包含&#xff1a; 完整源码数据库功能演示视频万字文档PPT 项目编码&#xff1…

TCP 连接状态标识 | SYN, FIN, ACK, PSH, RST, URG

注&#xff1a;本文为“TCP 连接状态标识”相关文章合辑。 TCP 的状态&#xff1a;SYN, FIN, ACK, PSH, RST, URG 简介及 ACK 确认机制 llzhang_fly 于 2020-09-19 05:25:26 发布 1、TCP 的状态 FLAGS 字段状态 在 TCP 层&#xff0c;有个 FLAGS 字段&#xff0c;这个字段有…

Spring AI 从入门到实践

​Spring AI 从入门到实践 1.什么是Spring AI 2.使用Spring Boot&Spring AI快速构建AI应用程序 3.ChatClient&Chat Model简化与AI模型的交互 4.Spring AI Prompt:与大模型进行有效沟通 5.结构化输出大模型响应 6.实战:AI聊天机器人 Ben技术站关注Java技术&#x…

1月13日学习

[HITCON 2017]SSRFme 直接给了源代码&#xff0c;题目名称还是ssrf&#xff0c;那么该题大概率就是SSRF的漏洞&#xff0c;进行代码审计。 <?php// 检查是否存在 HTTP_X_FORWARDED_FOR 头&#xff0c;如果存在&#xff0c;则将其拆分为数组&#xff0c;并将第一个 IP 地址…

【RDMA学习笔记】1:RDMA(Remote Direct Memory Access)介绍

从帝国理工的PPT学习。 什么是RDMA Remote Direct Memory Access&#xff0c;也就是Remote的DMA&#xff0c;是一种硬件机制&#xff0c;能直接访问远端结点的内存&#xff0c;而不需要处理器介入。 其中&#xff1a; Remote&#xff1a;跨node进行数据传输Direct&#xff…

Docker

1. 初始Docker 1.1. 什么是Docker&#xff1f; 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署&#xff0c;环…

Deep4SNet: deep learning for fake speech classification

Deep4SNet&#xff1a;用于虚假语音分类的深度学习 摘要&#xff1a; 虚假语音是指即使通过人工智能或信号处理技术产生的语音记录。生成虚假录音的方法有"深度语音"和"模仿"。在《深沉的声音》中&#xff0c;录音听起来有点合成&#xff0c;而在《模仿》中…

Navicat Premium 原生支持阿里云 PolarDB 数据库

近日&#xff0c;我司旗下的 Navicat Premium 软件通过了阿里云 PolarDB 数据库产品生态集成认证&#xff0c;这标志着 Navicat 通过原生技术全面实现了对秒级弹性、高性价比、稳定可靠的PolarDB 数据库三大引擎&#xff08;PolarDB MySQL版、PolarDB PostgreSQL版和 PolarDB f…

LabVIEW光流算法的应用

该VI展示了如何使用NI Vision Development Module中的光流算法来计算图像序列中像素的运动矢量。通过该方法&#xff0c;可以实现目标跟踪、运动检测等功能&#xff0c;适用于视频处理、机器人视觉和监控领域。程序采用模块化设计&#xff0c;包含图像输入、算法处理、结果展示…

JAVA:在IDEA引入本地jar包的方法(不读取maven目录jar包)

问题&#xff1a; 有时maven使用的jar包版本是最新版&#xff0c;但项目需要的是旧版本&#xff0c;每次重新install会自动将mavan的jar包覆盖到项目的lib目录中&#xff0c;导致项目报错。 解决&#xff1a; 在IDEA中手动配置该jar包对应的目录。 点击菜单File->Projec…

升级 SpringBoot3 全项目讲解 — 为什么 SpringBoot3 应该抛弃 Maven,搭配 Gradle 来使用?

学会这款 &#x1f525;全新设计的 Java 脚手架 &#xff0c;从此面试不再怕&#xff01; 随着 Spring Boot 3 的发布&#xff0c;许多开发者开始考虑如何将现有项目升级到最新版本。Spring Boot 3 带来了许多新特性&#xff0c;包括对 Java 17 的支持、更好的性能优化以及对 G…