java 导出pdf 获取前端echarts图片 拼接数据

   

【生成PDF】Java如何根据前台Echarts图表生成PDF,并下载_小小小鱼生的博客-CSDN博客_echart导出pdf

原帖子 填充数据有问题,无法填充,注意!注意!注意!!!!!

现已修改完成 

导入pom坐标


     com.itextpdf
    itextpdf
    5.5.13.3

前端获取echart图片方式

var myChart1;
//加载实时调用
function loadChart1(res)
{
    var colorList = ['#73DDFF', '#73ACFF'];
    myChart1 = echarts.init(document.getElementById('chart-visitTrend'));
    option = {
            /* title: {
              text: '审计调用统计'
            }, */
            tooltip: {
              trigger: 'axis'
            },
            legend: {
              data: ['接收', '发送']
            },
            grid: {
                top:'5%',
              left: '1%',
              right: '3%',
              bottom: '0%',
              containLabel: true
            },
            /* toolbox: { //保存图片
              show: true,
              orient: "vertical",
              itemSize: 12,
              feature: {
                saveAsImage: {
                    name:"实时调用下载"
                }
              }
            }, */
            xAxis: {
              type: 'category',
              boundaryGap: false,
              //data: ['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05', '2022-01-06', '2022-01-07']
              data:res.timeData
            },
            yAxis: {
              type: 'value',
              axisLabel: {
                  formatter: '{value} 次'
                }
            },
            series: [
              {
                //name: '',
                type: 'line',
                stack: 'Total',
                color: colorList[0],
                //data: [120, 132, 101, 134, 90, 230, 210]
                data:res.countData
              }
            ]
          };
    // 使用刚指定的配置项和数据显示图表。
    myChart1.clear();
    myChart1.setOption(option);
}


// 导出
doExport = function()
{
    //获取echarts图的base64编码,为png格式。
    var picBase64Info = myChart1.getDataURL();
    var con = getCondition();//其它条件
    con['picBase64Info'] = picBase64Info;

    var form =document.createElement("form");
    form.style.display='none';
    form.action ='/reportform/exportform';
    form.method = 'post';
    document.body.append(form);
    
    for(var key in con)
    {
        var input = document.createElement("input");
        input.type = "hidden";
        input.name = key;
        input.value = con[key];
        form.target = "exportFrame";
        form.appendChild(input);
    }
    form.submit();
    form.remove();

    // 以下通过ajax请求方式行不通,无法触发浏览器的下载动作
/*  
    $.ajax({
        url: '/reportform/exportform',
        type: "post",
        async: true,
        cache: false,
        data: JSON.stringify(con),
        contentType : "application/json",
        dataType: "json",
        error: function(xhr)
        {
           // 操作失败
        }
    }); */
}

picBase64Info 就是加密的数据

后端接口数据即可。

到控制层操作

 public void generatePdf(HttpServletResponse response, String picBase64Info) {
        // 1.创建文档,设置文档页面大小,页边距
        Document document =
                new Document(
                        PageSize.A4,
                        Float.parseFloat("0"),
                        Float.parseFloat("10"),
                        Float.parseFloat("44"),
                        Float.parseFloat("50"));

        // 2.解析前台传来的echart图,生成pdf段落元素
        Paragraph pictureEle =
                PDFUtil.createImageFromEncodeBase64(
                        picBase64Info,
                        "结果",
                        Float.parseFloat("60"),
                        Float.parseFloat("80"),
                        false);

        // 生成table表格段落
        // 获取所有的list数据,实体对应下面list的实体对象
        List basicAnalyses = details("1579758070935814145").getBasicAnalyses();
        // 对应实体的属性名 方便后续的反射取值
        ArrayList list = new ArrayList<>();
        list.add("flowcell");
        list.add("sampleName");
        list.add("sampleCode");
        list.add("totalBase");
        list.add("onTargetGt1000");
        list.add("conversionRatio");
        list.add("qcConclusion");
        list.add("ucas");
        Paragraph table1 =
                PDFUtil.createTable(
                        basicAnalyses,
                        "报告",
                        // 表格标题列数 与list 数量对应
                        new String[] {
                            "名称", "姓名", "编号", "数据量", "靶", "转", "s", "评分"
                        },
                        list);
        //主页标头
        Paragraph elements = new Paragraph("123123",PDFUtil.getCoverFontFont());
        // 将所有需要放到文档里的元素,汇总
        List paragraphs = new ArrayList<>();
        paragraphs.add(elements);
        paragraphs.add(pictureEle);
        paragraphs.add(table1);
        // paragraphs.add(table3);
        // 导出pdf文档:将paragraphs塞到document中,并下载document
        PDFUtil.exportDocument(document, null, paragraphs, response, "报表");
    }

package com.euler.eucas.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import com.euler.eucas.analysis.model.BasicAnalysis;
import com.euler.eucas.analysis.mybatis.entity.QualityControlEntity;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.springframework.beans.BeanUtils;

/**
 * @since JDK 1.8
 */
public class PDFUtil {
    private static final Logger logger = LogManager.getLogger(PDFUtil.class);

    /** fontSize_normal : (正文字体大小11号). */
    public static final float FONTSIZE_NORMAL = Integer.parseInt("11");
    /** fontSize_titile : (标题字体大小14号). */
    public static final float FONTSIZE_TITILE = Integer.parseInt("14");
    /** FONTSIZE_COVER : (封面字体大小32号). */
    public static final float FONTSIZE_COVER = Integer.parseInt("19");

    /** normalFont : (通用字体样式:宋体、11号). */
    private static Font normalFont = null;
    /** titleFont : (通用标题字体样式:宋体、14号、加粗). */
    private static Font titleFont = null;
    /** coverFont : (通用封面字体样式:宋体、28号、加粗). */
    private static Font coverFont = null;

    /**
     * getBaseFont : (获取可以解析中文的字体:使用宋体). 
* * @author * @return * @since JDK 1.8 */ public static BaseFont getBaseFontChinese() { try { // // 宋体资源文件路径,可以从C://Windows//Fonts//simsun.ttc拷贝到相应目录下 TODO 字体需要拷贝一份 // URL path = PDFUtil.class.getResource("/config/fonts/simsun.ttc"); // return BaseFont.createFont(path + ",0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 本地测试:使用windows自带的宋体文件 return BaseFont.createFont("C://Windows//Fonts//simsun.ttc,0", BaseFont.IDENTITY_H, false); } catch (Exception e) { logger.error("设置字体样式失败", e); return null; } } /** * getNormalFont : (获取普通字体样式).
* * @author * @return * @since JDK 1.8 */ public static Font getNormalFont() { if (normalFont == null) { BaseFont bfChinese = getBaseFontChinese(); normalFont = new Font(bfChinese, FONTSIZE_NORMAL, Font.NORMAL); } return normalFont; } /** * getTitleFont : (获取标题通用字体).
* * @author * @return * @since JDK 1.8 */ public static Font getTitleFont() { if (titleFont == null) { BaseFont bfChinese = getBaseFontChinese(); titleFont = new Font(bfChinese, FONTSIZE_TITILE, Font.BOLD); } return titleFont; } /** * getTitleFont : (获取封面通用字体).
* * @author * @return * @since JDK 1.8 */ public static Font getCoverFontFont() { if (coverFont == null) { BaseFont bfChinese = getBaseFontChinese(); coverFont = new Font(bfChinese, FONTSIZE_COVER, Font.BOLD); } return coverFont; } /** * getfieldValue : (通过反射,根据方法名,执行方法,最终返回行结果的toString值).
* * @author * @param 方法执行的入参 * @param object 对象 * @param methodName 方法名 * @param args 方法执行参数 * @since JDK 1.8 */ private static String getfieldValue(T object, String methodName, Object... args) { try { Field declaredField = object.getClass().getDeclaredField(methodName); declaredField.setAccessible(true); Object value = declaredField.get(object); return value == null ? "" : value.toString(); } catch (Exception e) { logger.error("getfieldValue error", e); return ""; } } /** * analysisPicBase64Info : (解析base64图片信息).
* * @author * @param picBase64Info 图片base64信息,或前台echart通过调用getDataURL()方法获取的图片信息 * @return 图片经过base64解码后的信息 * @since JDK 1.8 */ public static Element analysisPicBase64Info(String picBase64Info) { if (StringUtils.isEmpty(picBase64Info)) { // 空段落 return new Paragraph(); } // 1.获取图片base64字符串信息:若入参是通过前台echarts调用getDataURL()方法获取的,则该字符串包含逗号,且则逗号后面的内容才是图片的信息 String pictureInfoStr = picBase64Info.indexOf(",") == -1 ? picBase64Info : picBase64Info.split(",")[1]; // 2.将图片信息进行base64解密 byte[] imgByte = Base64.decodeBase64(pictureInfoStr); // 对异常的数据进行处理 /** * .图片的原始表达ascii码范围是0-255, .这里面有一些不可见的编码。然后为了图片正确传输才转成编码base64的0-63, * .当从base64转成byte时,byte的范围是[-128,127],那么此时就会可能产生负数,而负数不是在ascii的范围里,所以需要转换一下 */ for (int i = 0; i < imgByte.length; i++) { if (imgByte[i] < 0) { imgByte[i] += 256; } } try { return Image.getInstance(imgByte); } catch (Exception e) { logger.error("analysisPicBase64Info error", e); return new Paragraph(); } } /** * analysisPicBase64Info_batch : (批量解析base64加密的图片信息,生成Image对象).
* * @author * @param picBase64Infos 经过base64加密的图片信息 * @return * @since JDK 1.8 */ public static List analysisPicBase64Info_batch(List picBase64Infos) { List images = new ArrayList(); for (String li : picBase64Infos) { Element image = analysisPicBase64Info(li); images.add(image); } return images; } /** * createImage : (根据图片的base64加密文件创建pdf图片).
* * @author * @param picBase64Info base64加密后的图片信息(支持台echart通过调用getDataURL()方法获取的图片信息) * @param title 段落标题 * @param percentX 图片缩放比例X轴 * @param percentY 图片缩放比例Y轴 * @param titleCenter 标题是否居中,true-居中、false-默认居左 * @return 返回图片段落 * @since JDK 1.8 */ public static Paragraph createImageFromEncodeBase64( String picBase64Info, String title, float percentX, float percentY, boolean titleCenter) { // 1.获取图片 Element element = analysisPicBase64Info(picBase64Info); // 2.创建段落,并添加标题 Paragraph paragraph = new Paragraph(title, getTitleFont()); // 空行 paragraph.add(Chunk.NEWLINE); paragraph.add(Chunk.NEWLINE); if (titleCenter) { // 居中 paragraph.setAlignment(Element.ALIGN_CENTER); } else { // 居左 setDefaultIndentationLeft(paragraph); } if (!(element instanceof Image)) { // 图片解析失败 return paragraph; } Image image = (Image) element; // 3.设置图片缩放比例 //image.scalePercent(percentX, percentY); // image.scaleToFit(800,3000); image.scaleAbsolute(percentX,percentY); // 4.图片放入该段落 paragraph.add(image); return paragraph; } /** * createImageFromEncodeBase64_batch : (批量创建).
* * @author * @param picBase64Infos 图片base64加密后的信息(支持台echart通过调用getDataURL()方法获取的图片信息) * @param titles 段落标题 * @param percentXs X轴缩放比例 * @param percentYs Y轴缩放比例 * @param titleCenter 标题是否居中 * @return * @since JDK 1.8 */ public static Paragraph createImageFromEncodeBase64_batch( List picBase64Infos, List titles, List percentXs, List percentYs, boolean titleCenter) { Paragraph paragraphs = new Paragraph(); for (int i = 0; i <= picBase64Infos.size(); i++) { Paragraph imagePara = createImageFromEncodeBase64( picBase64Infos.get(i), titles.get(i), percentXs.get(i), percentYs.get(i), titleCenter); if (!imagePara.isEmpty()) { paragraphs.add(imagePara); // 空行 paragraphs.add(Chunk.NEWLINE); paragraphs.add(Chunk.NEWLINE); } } return paragraphs; } /** * createTable : (创建table段落).
* * @author * @param * @param list 构建table的数据 * @param title 该段落取的名字 * @param methodNames 需要调用的方法名,用来获取单元格数据。通常是某个属性的get方法 * @return * @since JDK 1.8 */ public static Paragraph createTable( List list, String title, String[] tableHead, List methodNames) { return createTable( list, FONTSIZE_NORMAL, FONTSIZE_TITILE, title, tableHead, methodNames, false); } /** * createTable : (创建table段落).
* * @author * @param * @param list 构建table的数据 * @param title 该段落取的名字 * @param methodNames 需要调用的方法名,用来获取单元格数据。通常是某个属性的get方法 * @param titleCenter 标题是否居中:true-居中,false-居左 * @return * @since JDK 1.8 */ public static Paragraph createTable( List list, String title, String[] tableHead, List methodNames, boolean titleCenter) { return createTable( list, FONTSIZE_NORMAL, FONTSIZE_TITILE, title, tableHead, methodNames, titleCenter); } /** * createTableByList : (创建table段落).
* * @author * @param * @param listData * @param normalFontSize 正文字体大小 * @param titleFontSize 标题字体大小 * @param title 段落名称 * @param methodNames 获取表格属性的方法名 * @param titleCenter 段落标题是否水平居中,true:需要居中;false:默认靠左 * @return * @since JDK 1.8 */ public static Paragraph createTable( List listData, float normalFontSize, float titleFontSize, String title, String[] tableHead, List methodNames, boolean titleCenter) { // 1.创建一个段落 Paragraph paragraph = new Paragraph(title, getTitleFont()); // 空行 paragraph.add(Chunk.NEWLINE); paragraph.add(Chunk.NEWLINE); if (titleCenter) { // 居中 paragraph.setAlignment(Element.ALIGN_CENTER); } else { // 居左 setDefaultIndentationLeft(paragraph); } // 3.创建一个表格 PdfPTable table = new PdfPTable(tableHead.length); // 列数 try { // 修改列宽。需要和列数对应 table.setWidths(new int[] {65,50,65,50,65,50,50,50}); } catch (DocumentException e) { e.printStackTrace(); } paragraph.add(table); // 4.构造表头 for (String head : tableHead) { head = StringUtils.isEmpty(head) ? "" : head; PdfPCell cell = new PdfPCell(new Paragraph(head, getNormalFont())); cell.setBackgroundColor( new BaseColor( Integer.parseInt("124"), Integer.parseInt("185"), Integer.parseInt("252"))); // 背景色 cell.setMinimumHeight(Float.parseFloat("15")); // 单元格最小高度 cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 水平居中 table.addCell(cell); } if (CollectionUtils.isEmpty(listData)) { // 没有数据,添加一行空单元格,并返回 for (int i = 0; i < methodNames.size(); i++) { table.addCell(new Paragraph(" ")); // 有一个空格,否则添加不了 } return paragraph; } // 5.构造table数据 for (T li : listData) { // 反射获取名字和存入的名字比较相等获取属性值存入 for (String name : methodNames) { String valueStr = getfieldValue(li, name); PdfPCell cell = new PdfPCell(new Paragraph(valueStr, getNormalFont())); cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 水平居中 table.addCell(cell); } } // 5.返回 return paragraph; } /** * addToTable : (从段落中找到第一个table,向该table中追加数据).
* ().
* * @author * @param * @param paragraph * @param listData * @param methodNames * @since JDK 1.8 */ public static void addToTable( Paragraph paragraph, List listData, List methodNames) { for (Element ele : paragraph) { if (!(ele instanceof PdfPTable)) { // 不是table元素,直接跳过 continue; } // 找到第一个table元素 PdfPTable table = (PdfPTable) ele; for (T data : listData) { for (String name : methodNames) { String valueStr = getfieldValue(data, name); PdfPCell cell = new PdfPCell(new Paragraph(valueStr, getNormalFont())); cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 水平居中 table.addCell(cell); } } break; } } /** * exportDocument : (生成并下载PDF文档).
* ().
* * @author * @param document 文档对象 * @param cover 封面:若不是null,则会先添加封面,并另起新页面添加段落 * @param paragraphs 需要组成PDF文件的段落 * @param response 请求的响应对象 * @param fileName 生成的文件名称,不需要加pdf后缀 * @since JDK 1.8 */ public static void exportDocument( Document document, Paragraph cover, List paragraphs, HttpServletResponse response, String fileName) { try (ServletOutputStream out = response.getOutputStream()) { response.setContentType("application/pdf;charset=UTF-8"); response.setHeader( "Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName + ".pdf", "UTF-8")); PdfWriter.getInstance(document, out); // 打开文档 document.open(); if (cover != null) { document.add(cover); // 起新页面 document.newPage(); } StringBuilder errorMsg = new StringBuilder(); for (int i = 0; i < paragraphs.size(); i++) { try { // 将段落添加到文档 document.add(paragraphs.get(i)); // 空行 document.add(Chunk.NEWLINE); document.add(Chunk.NEWLINE); } catch (DocumentException e) { errorMsg.append("PDF文件生成出错,请检查第:").append(i).append("个段落"); } } if (!StringUtils.isEmpty(errorMsg.toString())) { logger.error(errorMsg); } // 关闭文档 document.close(); out.flush(); } catch (Exception e) { logger.error("生成PDF文档并下载,出错:", e); } } /** * setDefaultIndentationLeft : (设置段落标题默认左边距).
* * @author * @param paragraph * @since JDK 1.8 */ public static void setDefaultIndentationLeft(Paragraph paragraph) { paragraph.setIndentationLeft(Float.parseFloat("30")); } /** * addBlankLine : (添加空行).
* * @author * @param paragraph 需要添加空行的段落 * @param lineNum 需要添加空行的个数 * @since JDK 1.8 */ public static void addBlankLine(Paragraph paragraph, int lineNum) { if (paragraph == null) { return; } for (int i = 0; i < lineNum; i++) { paragraph.add(Chunk.NEWLINE); } } }

结果

java 导出pdf 获取前端echarts图片 拼接数据_第1张图片

你可能感兴趣的:(java,开发语言)