关于echarts图片(多图)上传后插入pdf中导出新的带有统计图的问题。

项目思路:由于使用的是freemarker所以要先将ftl转化成html文件然后再将HTML转化成pdf文件,所以思路就来了!

1、在ftl文件的界面显示echarts图并且在每个table下面初始化一个统计图。(关于统计图的初始化这里就不在赘述),其次是动态加载数据由于使用js加载界面的所以必须要从后台拿到一个json集合然后再遍历代码如下:

 let studentsXinlv = data.xinlvs;
        for (let i = 0; i < studentsXinlv.length; i++) {
             if (studentsXinlv[i].showName === '合计' && studentsXinlv[i].gender === '男') {
                    xloption.series[0].data[0] = studentsXinlv[i].zhengchanglv;
                    xloption.series[0].data[1] = studentsXinlv[i].guohuanlv;
                    xloption.series[0].data[2] = studentsXinlv[i].guosulv;
                    xloption.series[0].data[3] = studentsXinlv[i].zayinlv;
      } else if (studentsXinlv[i].showName === '合计' && studentsXinlv[i].gender === '女') {
                    xloption.series[1].data[0] = studentsXinlv[i].zhengchanglv;
                    xloption.series[1].data[1] = studentsXinlv[i].guohuanlv;
                    xloption.series[1].data[2] = studentsXinlv[i].guosulv;
                    xloption.series[1].data[3] = studentsXinlv[i].zayinlv;
           }
      }

现在图生成了那如何拿到生成统计图的图片呢?这就用到了

let imgs = echarts.getDataURL({type: 'png'});

获取到每个echarts的base64位的png图片!

强烈建议!!!如果在后台下载并将文件放在header中存储,在前端显示下载,这样的问题千万千万别用ajax发请求!!!因为ajax发送的请求后返回的是json对象,也就是字符流,而文件是二进制保存的所以就会出现乱码一样的东西,不是你想要的文件!

解决这类问题需要发送表单!那如何携带多图片发送表单呢?代码如下:

$("#allimg").append($("<input type='hidden' name='imgs' value='" + imgs + "'/>"));

需要在body里面申明一个form

<div>
    <form id="allImgSubmit" action="${base}/manage/control/jiancebaogao/tongjiimg" method="post">
        <input type="hidden" name="year" value="${currentYear!}"/>
        <input id="allimg" type="hidden" name="schoolId" value="${(school.id?c)!}"/>
    </form>
</div>

最后别忘了submit()表单!

重头戏来了!!!!!!

java后端:

首先是关于参数接收的问题:其他参数传什么用什么来接(一般是string但是传的和接收的名字需要一致)

图片接收需要的是一个字符数组String[] allimg保证能接收到!

那接收到任何如何转换呢?这些别人博客上面也有,我也是抄的博客上面的修修改改,是好几天前的了所以就不一个个去找了,在这里我直接粘代码,有和别人一样的请见谅!

将base64位的图片转成正常图片并保存在文件中:上干货!

maven依赖:

<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.6</version>
        </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.12</version>
        </dependency>

图片64位转png图片 

import sun.misc.BASE64Decoder;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
 * 描述:将64位字节转换为图片类型存储
 * @author tuoxw
 * imgPath :存储图片的路径
 *dateUrl:64为字节的图片 类似于:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlgA。。。
 * imgName 自定义的图片名称
 * */
public class Base64ToImg {
    public static void base64ToImg(String imgPath,String imgName,String dateUrl) throws IOException {
        BASE64Decoder decoder = new BASE64Decoder();
        String[] split = dateUrl.split(",");
        byte[] bytes = decoder.decodeBuffer(split[1]);
        for (int i = 0; i < bytes.length; ++i) {
            if (bytes[i] < 0) {
                // 调整异常数据
                bytes[i] += 256;
            }
        }
        OutputStream out = new FileOutputStream(imgPath + "/"+imgName+".png");
        out.write(bytes);
        out.flush();
        out.close();
    }
}

多图片?那好办!!

 for (int i = 0; i < imgs.length; i++) {
            String name = "" + i;
            pngs [i] = imgBasePath +File.separator + name + ".png";
            Base64ToImg.base64ToImg(imgBasePath, name, imgs[i]);
        }

那个pngs是做铺垫,后面能用得上记得给申明一下哈!

好了图片拿到了,那pdf呢?这要用到文件流了(在这里拿到的pdf是处理过的,也就是前端页面转换的时候一定要留够空白页这样好将图片插进去)

import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

import java.io.FileOutputStream;
import java.io.IOException;

public class AddImgToPDF {
    public static void addSeal(int []pages, String savePdf, String []pngs, String sealPdf) throws IOException {
        int marginLeft = 400;// 左边距
        int marginBottom = 50;// 底边距
        PdfReader pdfreader = new PdfReader(savePdf);
        // 获得PDF总页数
        int pdfPage = pdfreader.getNumberOfPages();
        for (int i = 0; i < pages.length; i++) {
            if (pages[i] <= 0 || pages[i] > pdfPage) {
                System.out.println("pdf文件无当前页");
            }
        }
            // 获取指定页的宽和高
            if (pdfreader != null)
                pdfreader.close();
            PdfReader pdf = new PdfReader(savePdf);
            PdfStamper stamper = null;
            Document document = null;
            try {
                stamper = new PdfStamper(pdf, new FileOutputStream(sealPdf));// 生成的PDF
                for (int i = 0; i < pngs.length; i++) {
                    document = new Document(pdfreader.getPageSize(pages[i]));
                    PdfContentByte overContent = stamper.getOverContent(pages[i]);
                    Image image = Image.getInstance(pngs[i]);// 图片名称
                   // image.setAbsolutePosition(75,marginBottom);// 左边距、底边距
                    image.setAbsolutePosition(75,marginBottom);// 左边距、底边距
                    image.scalePercent(50, 75);
                    overContent.addImage(image);
                    overContent.stroke();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (document != null){
                        document.close();
                    }
                    if (null != stamper) {
                        stamper.close();
                    }
                    if (pdf != null) {
                        pdf.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
    }
}

这里要对该方法说明一下:

1、[]pages:你拿到pdf的空白页的页码(多个空白页)。

2、savepdf:是你需要处理的pdf文件(全路径:*******.pdf)

3、pngs是你拿到的图片(全路径*******.png,前面的铺垫用上了传进来就行)

4、后面那个是pdf输出路径(全路径:*****.pdf)

方法参数说明: image.scalePercent(50, 75);是等比例缩放图片

遗留问题:虽然导出来了带图片的pdf文件但是那个pdf的空白页码总是是写死的感觉不爽那怎么办?这个本人搜了好多资料暂未解决!!有知道的小伙伴可以私聊我!我的解决方法是这样的:

既然每一页是确定的(空白页和图片)我需要得到最后一页pdf页码然后依次去减就能得到每一页的空白页

int[] emptyPdfPage = new int[]{(pages-23),(pages-21),(pages-19),(pages-17),(pages-15),(pages-13),(pages-11),(pages-8),(pages-6),(pages-4),pages};

这样就能实现动态的赋值,问题是如果统计表的数据多少不确定那么这个方法就不可行!!

附加:获取pdf页码的代码:

import com.itextpdf.text.pdf.PdfReader;

import java.io.IOException;
import java.io.InputStream;


public class EmptyPagesToPDF {
    public static Integer pages(String inpdfPath) throws IOException {
        InputStream inputStream = InputStreamUtil.getInputStream(inpdfPath);
        byte[] pdfbyte = InputStreamUtil.toByteArray(inputStream);
        PdfReader reader = new PdfReader(pdfbyte);
        // 获取页码
        int pages = reader.getNumberOfPages();
        reader.close();
        return pages;
    }
}

声明:以上代码有众多是借鉴的别人代码,然后修改的!!此次主要是分享个人心得以及对于该类问题的一种思路!希望对需要帮助的人有用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值