将html网页展示的图表,下载到PPT文档内,以图片的形式展示在PPT内

使用到的工具有:
开发工具:IDEA
报表开发工具:帆软10.0.19
1、针对帆软报表[普通报表]的设置
1.1首先选中在帆软里制作好的报表,选择模板web属性
在这里插入图片描述
1.2.选择数据分析模式,添加一个事件设置,该事件应该设置“加载结束”
在这里插入图片描述
1.3.在Js脚本里写这段代码:

var node = document.getElementsByClassName('x-table')[0].parentElement;
var message = {
	nodeId: '自定义一个别名',
	nodeInnerHTML: node.innerHTML
};
window.parent.postMessage(message, '*');

在这里插入图片描述
–绘制表格及如何将帆软报表展示到html不做过多赘述

给生成PPT方法添加一个按钮事件:

$("#DOWNLOAD").on("click", function () {
        
        //给每个表格设置一个新的ID
        updateTableId();

        var timeBucket = $("#inqu_status-0-timeBucket").val();
        let orderYear = timeBucket.substring(0, 4)
        let orderMonth = timeBucket.substring(4, 6)
        let orderYearC = orderYear + '年'
        let orderMonthC = orderMonth + '月'

        var inInfo = new EiInfo();
        var promises = []; // 存储生成图片的 Promise

		//确保每个table都生成了BASE64编码
        document.querySelectorAll(".html2canvas table").forEach((v, k, p) => {
            var promise = html2canvas(document.querySelector('#' + v.id), {}).then((canvas) => {

                //根据当前id获取tr的数量。1tr假设等于11PX 从而计算出数据表格的高度
                let tableHeight = v.querySelectorAll("tr").length * 11;
                let src = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); // 将canvas转换成img的src流
                console.log(v.id, k)
                inInfo.set(v.id, src)
                inInfo.set(v.id + 'Height', tableHeight.toString())
                
            });
            promises.push(promise);
        })


		//所有报表的base64编码都在promises里后,调用后台服务
        Promise.all(promises).then(() => {
            inInfo.set("{{Year}}", `${orderYear}`)
            inInfo.set("{{Month}}", `${orderMonth}`)
            inInfo.set("{{YearC}}", `${orderYearC}`)
            inInfo.set("{{MonthC}}", `${orderMonthC}`)
            inInfo.set("{{YearMonth}}", `${orderYear}${orderMonth}`)
            inInfo.set("{{YearMonthC}}", `${orderYearC}${orderMonthC}`)

            var jsonEi = inInfo.toJSONString(true);
            console.log(jsonEi)
            post(IPLATUI.CONTEXT_PATH + "/DownloadAgree", {"temporaryId": "PM15", "jsonEi": jsonEi});

            // IPLAT.progress($("#result"), false);
        });

        IPLAT.progress($("#result"), false);

        

    })
function updateTableId() {
    var tables = document.querySelectorAll("table[class^='x-table']");
    for (var i = 0; i < tables.length; i++) {
        tables[i].setAttribute("id", "newTableId" + i);
        num = i;
    }
}

调用后台:DownloadAgree,通过该服务,去调用具体实现方法

package com.baosight.bgdsp.rp.pm;

import com.baosight.iplat4j.core.ei.EiConstant;
import com.baosight.iplat4j.core.ei.EiInfo;
import com.baosight.iplat4j.core.service.soa.XLocalManager;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class DownloadAgree extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) {
		EiInfo eiInfo = EiInfo.parseJSONString(request.getParameter("jsonEi"));
		String temporaryId = request.getParameter("temporaryId");
		if (temporaryId.equals("PM")) {
			eiInfo.set("response", response);
			eiInfo.set(EiConstant.serviceName, "RPPM07");
			eiInfo.set(EiConstant.methodName, "exportPPT");
			eiInfo = XLocalManager.callNewTx(eiInfo);

		}if (temporaryId.equals("PM15")) {
			eiInfo.set("response", response);
			eiInfo.set(EiConstant.serviceName, "RPPM15");
			eiInfo.set(EiConstant.methodName, "exportPPT");
			eiInfo = XLocalManager.callNewTx(eiInfo);

		}

	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		doGet(request, response);
	}
}

exportPPT方法:

public EiInfo exportPPT(EiInfo inInfo) throws IOException {
        HttpServletResponse response = (HttpServletResponse) inInfo.get("response");
        // 创建一个空的演示文稿
        String url = "";
        String os = System.getProperty("os.name").toLowerCase();
        boolean isMacOS = os.contains("mac");
        if (isMacOS) {
            url = PlatApplicationContext.getProperty("bgdsp." + projectEnv + ".share.template.mac");
        } else {
            url = PlatApplicationContext.getProperty("bgdsp." + projectEnv + ".share.template");
        }
        String tempName = PlatApplicationContext.getProperty("bgdsp." + projectEnv + ".share.template.rppm15");
        // 读取模板文件
        //InputStream resource = new ClassPathResource("/Users/apple/Desktop/-job/2022-development/iplat4j/渠道长龄库存压降情况汇报_template.pptx").getInputStream();
        FileInputStream inputStream = new FileInputStream(url + tempName);
//        FileInputStream inputStream = new FileInputStream("E://" + tempName);
        // 根据模板,创建一个新的ppt文档
        XMLSlideShow ppt = new XMLSlideShow(inputStream);
        // 读取模板PPT
        inputStream.close();

        Map<String, String> attr = inInfo.getAttr();
        attr.put("netPrice_2", getReportsToimage());

//        List<XSLFSlide> slides = ppt.getSlides();
        // 得到每页ppt
        XSLFSlide[] slides = ppt.getSlides().toArray(new XSLFSlide[0]);
        // 遍历ppt,填充模板
        for (XSLFSlide slide : slides) {
//            List<XSLFShape> shapes = slide.getShapes();
            XSLFShape[] shapes = slide.getShapes().toArray(new XSLFShape[0]);
            // 遍历每页ppt中待填充的形状组件
            for (XSLFShape shape : shapes) {
                if (shape instanceof XSLFTextShape) {
                    // 替换文本
                    XSLFTextShape textShape = (XSLFTextShape) shape;
                    String textValue = textShape.getText();
                    String shapeName = textShape.getShapeName();
                    boolean flag = false;
                    for (String text : extractContent(textValue)) {
                        if (attr.containsKey(text)) {
                            flag = true;
                            //使用mustache语法替换文字 {{YearC}}营{{MonthC}}销预案会
                            textValue = textValue.replace(text, attr.get(text));
                        }
                    }
                    if (flag && StringUtils.isNotBlank(textValue)) {
                        List<XSLFTextParagraph> paragraphs = textShape.getTextParagraphs();
                        for (XSLFTextParagraph paragraph : paragraphs) {
                            List<XSLFTextRun> textRuns = paragraph.getTextRuns();
                            for (XSLFTextRun textRun : textRuns) {
                                textRun.setText("");
                            }
                        }
                        XSLFTextRun textRun2 = textShape.getTextParagraphs().get(0).getTextRuns().get(0);

                        textRun2.setText(textValue);
                    }
                } else if (shape instanceof XSLFPictureShape) {
                    XSLFPictureShape pictureShape = (XSLFPictureShape) shape;
                    XSLFPictureData pictureData = pictureShape.getPictureData();
                    String imageName = pictureShape.getShapeName();
                    String imageBase64 = attr.get(imageName);
                    if (imageBase64 != null) {
                        byte[] bt = Base64.getDecoder().decode(imageBase64.split(",")[1]);
                        XSLFPictureData idx = ppt.addPicture(bt, PictureData.PictureType.PNG);
                        XSLFPictureShape pic = slide.createPicture(idx);
                        Rectangle2D anchor = pictureShape.getAnchor();
                        //高度取决于数据表格的条数 宽度固定
                        pic.setAnchor(new Rectangle2D.Double(anchor.getX(), anchor.getY(), anchor.getWidth(), anchor.getHeight()));
                        pictureShape.setAnchor(new Rectangle2D.Double(10, 0, 0, 0));
                    }
                }
            }
        }
        String fileName = "PPT名字" + DateUtils.curDateTimeStr14() + ".pptx";
        // 保存PPT文件
        //设置输出文件类型为pptx文件
        response.setContentType(CONTENT_TYPE_OF_PPT);
        response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, CHARSET_OF_UTF8));
        response.setHeader("Pragma", URLEncoder.encode(fileName, CHARSET_OF_UTF8));
        ServletOutputStream outputStream = response.getOutputStream();
        ppt.write(outputStream);
        outputStream.flush();
        outputStream.close();
        return new EiInfo();

    }

extractContent方法:

public static List<String> extractContent(String input) {
        List<String> contents = new ArrayList<>();
        int startIndex = input.indexOf("{{");
        while (startIndex != -1) {
            int endIndex = input.indexOf("}}", startIndex);
            if (endIndex != -1) {
                String content = input.substring(startIndex, endIndex + 2);
                contents.add(content);
                startIndex = input.indexOf("{{", endIndex);
            } else {
                break;
            }
        }
        return contents;
    }

getReportsToimage()方法:该方法针对的是:帆软报表的普通报表中,出现非表格报表的处理方法[即:柱状图、折线图等],通过直接访问帆软链接的方式去获取表格的base64编码。

private String getReportsToimage() throws IOException {
        String reportAddress = PlatApplicationContext.getProperty("bgdsp." + projectEnv + ".report.address");
        // 创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        try {
            // 构造请求URL
            String apiUrl = reportAddress + "/rp/pm/netPrice_2.cpt&format=image&extype=JPG";
            // 创建HttpGet请求
            //HttpPost request = new HttpPost(apiUrl);
            System.out.println("apiUrl");
            System.out.println(apiUrl);
            HttpGet httpGet = new HttpGet(apiUrl);
            // 设置请求头部
            httpGet.addHeader("Content-Type", "text/html; charset=utf-8");
            // 发送请求并获取响应
            HttpResponse responsed = httpClient.execute(httpGet);
            // 解析响应数据
            HttpEntity entity = responsed.getEntity();
            // 检查响应是否成功
            if (responsed.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 获取Content-Type头部信息
                Header contentTypeHeader = entity.getContentType();
                String contentType = contentTypeHeader.getValue();
                // 获取输入流
                InputStream inStream = entity.getContent();
                ByteArrayOutputStream outputStream_u = new ByteArrayOutputStream();

                // 将图片裁剪为宽60px,高60px
                BufferedImage originalImage = ImageIO.read(inStream);
                BufferedImage croppedImage = originalImage.getSubimage(0, 0, 3560, 1560);

                // 将裁剪后的图片转换成字节数组
                ByteArrayOutputStream outputStream_c = new ByteArrayOutputStream();
                ImageIO.write(croppedImage, "png", outputStream_c);
                byte[] croppedImageBytes = outputStream_c.toByteArray();

                // 将图片数据编码为base64格式
                String base64Image = Base64.getEncoder().encodeToString(croppedImageBytes);
                System.out.println(base64Image);
                String responseBody = EntityUtils.toString(entity);
                // 处理响应数据
                System.out.println(responseBody);
                // 关闭输入流和输出流
                inStream.close();
                outputStream_u.close();
                return "data:image/png;base64," + base64Image;
            } else {
                System.out.println("HTTP请求失败!");
            }


        } catch (PlatException e) {

        }
        return "";
    }

最后,在设置PPT模板的时候,将模板内的图片设置为修改后的别名:newTableIdi

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用甘特图实现高效时间规划

甘特图虽然看似简单,却蕴含着规划时间的奥秘。它将复杂的工序分解成逻辑严密的任务链条,每个短小的条形图块都清晰地道出一个任务的起始、持续和终止。就像指挥家挥舞手中的棒,每个动作都精确拍着节奏,确保各个乐手分工合作、行云流水。择一个好用的甘特图制作工具,会让你事半功…

HCIP作业

实验要求&#xff1a; 1、R6为ISP&#xff0c;接口IP地址均为公有地址&#xff0c;该设备只能配置IP地址&#xff0c;之后不能再对其进行任何配置&#xff1b; 2、R1-R5为局域网&#xff0c;私有IP地址192.168.1.0/24&#xff0c;请合理分配&#xff1b; 3、R1、R2、R4&#x…

空间解析几何之直线与平面:推导直线与直线、直线与平面交点

空间解析几何——直线与平面 三维空间中的直线和平面与二维空间中的性质有一定的类似之处&#xff0c;但是其相交关系的求解方式有所差异。本文回顾了三维空间中直线和平面的解析表达&#xff0c;然后推导线-线、线-面交点。 平面 空间平面的表达式为&#xff1a; A x B y…

React状态管理库快速上手-Redux(一)

基本使用 安装 pnpm install reduxjs/toolkit react-redux创建一个仓库 定义state createSlice相当于创建了一个模块仓库&#xff0c;initialState存放状态&#xff0c;reducers存放改变状态的方法。 import { createSlice } from reduxjs/toolkitexport const counterSli…

MATLAB环境下基于改进最大相关峭度解卷积的滚动轴承故障诊断

相关峭度解卷积MCKD是一种新的解卷积方法&#xff0c;其设计了一个新的目标函数—相关峭度&#xff0c;并以此为优化目标设计一系列的FIR滤波器&#xff0c;为实现最好的效果&#xff0c;需要从中找到最优滤波器并最终实现对信号中噪声的抑制和对信号中冲击成分的突出的目的。M…

产品推荐 | 基于XC7K325T的FMC接口万兆光纤网络验证平台

01、产品概述 TES307是一款基于XC7K325T FPGA的万兆光纤网络验证平台&#xff0c;板卡具有1个FMC&#xff08;HPC&#xff09;接口&#xff0c;4路SFP万兆光纤接口、4路SATA接口、1路USB3.0接口。 板载高性能的FPGA处理器可以实现光纤协议、SATA总线控制器、以及USB3.0高速串…

长安链Docker Java智能合约引擎的架构、应用与规划

#功能发布 长安链3.0正式版发布了多个重点功能&#xff0c;包括共识算法切换、支持java智能合约引擎、支持后量子密码、web3生态兼容等。我们接下来为大家详细介绍新功能的设计、应用与规划。 在《2022年度长安链开源社区开发者调研报告》中&#xff0c;对Java合约语言支持是开…

华为配置HTTPS服务器实验

配置HTTPS服务器示例 组网图形 图1 配置HTTPS服务器组网图 组网需求配置思路配置注意事项操作步骤配置文件 组网需求 如图1所示&#xff0c;用户通过Web方式访问网关设备AP。 为了防止传输的数据不被窃听和篡改&#xff0c;实现对设备的安全管理&#xff0c;网络管理员要…

Makefile编译make complie时报错的心路历程

本次报错是在Makefile文件里面找错 Makefile文件找错的方法很复杂&#xff0c;必须要有一双慧眼&#xff0c;一层一层剥离分析 第一个错误&#xff08;还有一个错在全志 76节 23&#xff1a;35的时候连接wiringPi库&#xff09; 第二个错误&#xff1a; undefined reference…

Java:类和对象

目录 1.面对对象的初步认识1.1 什么是面向对象&#xff1f;&#xff08;Java当中一切皆为对象&#xff09;1.2 面对对象与面对过程 2.类的定义和使用2.1简单认识类2.2 类的定义格式 3.类的实例化3.1 什么是实例化3.2类和对象的说明 4.this引用4.1为什么要使用this引用4.2 什么是…

docker小白第十四天之Portainer与CIG

Portainer简介 Portainer是一款轻量级的应用&#xff0c;它提供了图形化界面&#xff0c;用于方便地管理Docker环境&#xff0c;包括单机环境和集群环境。 Portainer命令安装 # 一个容器可以同时起多个-p端口&#xff0c;restartalways表示随时在线&#xff0c;重启机器后也…

O2OA红头文件流转与O2OA版式公文编辑器基本使用

O2OA开发平台在流程管理中&#xff0c;提供了符合国家党政机关公文格式标准&#xff08;GB/T 9704—2012&#xff09;的公文编辑组件&#xff0c;可以让用户在包含公文管理的项目实施过程中&#xff0c;轻松地实现标准化公文格式的在线编辑、痕迹保留、手写签批等功能。并且可以…

[uni-app] uni.createAnimation动画在APP端无效问题记录

文章目录 uni.createAnimation动画描述动画代码templatejs部分 问题原因改进方案template js部分改动git 改进截图 uni.createAnimation 动画描述 实现一个以左上角为锚点,以Z轴做平面抬起及落下的动画效果 动画代码 template <image v-if"showHot(item.cname)&quo…

锂电极片生产中机器视觉系统的多元检测能力

随着新能源行业的快速发展&#xff0c;锂电池作为核心组件&#xff0c;其生产质量受到了前所未有的关注。在锂电极片的生产过程中&#xff0c;机器视觉系统以其高精度、高效率的特点&#xff0c;成为了保障产品质量的关键工具。本文将探讨机器视觉系统在锂电极片生产中可以检测…

WanAndroid(鸿蒙版)开发的第六篇

前言 DevEco Studio版本&#xff1a;4.0.0.600 WanAndroid的API链接&#xff1a;玩Android 开放API-玩Android - wanandroid.com 其他篇文章参考&#xff1a; 1、WanAndroid(鸿蒙版)开发的第一篇 2、WanAndroid(鸿蒙版)开发的第二篇 3、WanAndroid(鸿蒙版)开发的第三篇 …

GO语言:函数、方法、面向对象

本文分享函数的定义、特性、defer陷阱、异常处理、单元测试、基准测试等以及方法和接口相关内容 1 函数 函数的定义 func 函数名(参数列表) (返回值列表) { // 函数体&#xff08;实现函数功能的代码&#xff09; } 匿名函数的定义就是没有函数名&#xff0c;可以当做一个函…

第十九章 linux部署scrapyd

文章目录 1. linux部署python环境1. 部署python源文件环境2. 下载python3. 解压安装包4. 安装5. 配置环境变量6. 检查是否安装成功7. 准备python使用的包8. 安装scrapyd 1. linux部署python环境 1. 部署python源文件环境 yum install gcc patch libffi-devel python-devel zl…

【源码阅读】EVMⅢ

参考[link](https://blog.csdn.net/weixin_43563956/article/details/127725385 大致流程如下&#xff1a; 编写合约 > 生成abi > 解析abi得出指令集 > 指令通过opcode来映射成操作码集 > 生成一个operation 以太坊虚拟机的工作流程&#xff1a; 由solidity语言编…

WordPress站点如何实现发布文章即主动推送到神马搜索引擎?

平时boke112百科很少关注到神马搜索引擎&#xff0c;近日有站长留言想要实现WordPress站点发布文章就主动推送到神马搜索引擎&#xff0c;而且推送成功就自动添加一个自定义字段&#xff0c;以防重复推送。 登录进入神马站长平台后才知道神马也有一个API推送功能&#xff0c;不…

软件工程-第11章 内容总结

如果不想读这本书&#xff0c;直接看这一章即可。 11.1 关于软件过程范型 11.2 关于软件设计方法
最新文章