About echarts pictures (multi-pictures) uploaded and inserted into pdf to export new pictures with statistics.

Project ideas: Since you are using freemarker, you need to first convert ftl to HTML file and then HTML to pdf file, so the idea is here!

1. Display echarts diagram in the interface of ftl file and initialize a statistical diagram under each table. (Initialization of the statistical graph is not covered here. Secondly, dynamic loading data, because it uses the js loading interface, must get a json collection from the background and iterate through the code as follows:

 let studentsXinlv = data.xinlvs;
        for (let i = 0; i < studentsXinlv.length; i++) {
             if (studentsXinlv[i].showName === 'Total' && studentsXinlv[i].gender === 'male') {
                    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 === 'Total' && studentsXinlv[i].gender === 'female') {
                    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;

Now the graph generates that picture, how do I get the statistics?This is used

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

Get a base64-bit png picture of each echarts!

Highly recommended!!!If you download in the background and store the file in the header, and display the download in the front, do not make requests with ajax!!!Because the request sent by Ajax returns a json object, that is, a character stream, and the file is binary saved, something like random code will appear, not the file you want!

To solve this kind of problem, you need to send a form!How can I send a form with multiple pictures?The code is as follows:

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

You need to declare a form inside the body

    <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)!}"/>

Finally, don't forget the submit() form!

The big show is coming!!!!!

java backend:

First, there's a question about parameter reception: what and what other parameters pass (typically string s, but the passed and received names need to be the same)

Picture reception requires a character array String[] allimg guaranteed to be received!

So how do you receive any conversion?These other people's blogs also have, and I am also a copy of the blog above the modifications, is several days ago, so not one by one to find, here I directly stick code, there is the same excuse as others!

Turn base64-bit pictures into normal pictures and save them in a file: Go dry!

maven dependency:

<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->

Picture 64-bit to png pictures 

import sun.misc.BASE64Decoder;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
 * Description: Convert 64-bit bytes to picture type storage
 * @author tuoxw
 * imgPath :Path to store pictures
 *dateUrl: 64 Pictures in bytes are similar to: image/png;Base64, iVBORw0KGgoAANSUhEUgAAAlgA.
 * imgName Custom picture name
 * */
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) {
                // Adjust Exception Data
                bytes[i] += 256;
        OutputStream out = new FileOutputStream(imgPath + "/"+imgName+".png");

More pictures?That's fine!!

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

That pngs is a pad, so you can remember to declare it later!

Now that the pictures are available, what about pdf?This uses file streams (the PDF you get here is handled, that is, you have to leave enough blank pages to insert pictures when converting front-end pages)

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;// left
        int marginBottom = 50;// Bottom margin
        PdfReader pdfreader = new PdfReader(savePdf);
        // Get PDF Total Pages
        int pdfPage = pdfreader.getNumberOfPages();
        for (int i = 0; i < pages.length; i++) {
            if (pages[i] <= 0 || pages[i] > pdfPage) {
                System.out.println("pdf File has no current page");
            // Gets the width and height of the specified page
            if (pdfreader != null)
            PdfReader pdf = new PdfReader(savePdf);
            PdfStamper stamper = null;
            Document document = null;
            try {
                stamper = new PdfStamper(pdf, new FileOutputStream(sealPdf));// Generated 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]);// Picture Name
                   // image.setAbsolutePosition(75,marginBottom);//Left margin, bottom margin
                    image.setAbsolutePosition(75,marginBottom);// Left margin, bottom margin
                    image.scalePercent(50, 75);
            } catch (Exception e) {
            } finally {
                try {
                    if (document != null){
                    if (null != stamper) {
                    if (pdf != null) {
                } catch (Exception e) {


Here is an explanation of the method:

1, []pages: You get the page number of the blank page of the pdf (multiple blank pages).

2, savepdf: is the PDF file you need to process (full path: *****.pdf)

3. pngs are the pictures you get (full path*****.png, the front padding is uploaded in)

4. The next one is the PDF output path (full path: *****.pdf)

Method parameter description: image.scalePercent(50, 75);Is a scaled picture

Legacy Question: Even though a pdf file with pictures has been exported, the blank page number of that pdf always feels uncomfortable when it is written to death. What can I do?This person has searched a lot of data and has not solved yet!!A little buddy with knowledge can chat with me privately!My solution is as follows:

Now that each page is determined (blank pages and pictures), I need to get the pdf page number of the last page and subtract it one by one to get the blank pages for each page

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};

In this way, dynamic assignment can be achieved. The problem is that this method is not feasible if the data of the statistical tables is uncertain!!

Attach: Code to get pdf page number:

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);
        // Get Page Number
        int pages = reader.getNumberOfPages();
        return pages;

Statement: There are many other codes that you can use for reference and then modify!!This time, it is mainly to share personal experience and a way of thinking about this kind of problem!Hope to be useful to those who need help!

Keywords: Javascript html echarts xpdf

Added by RoundPorch on Thu, 02 Sep 2021 02:50:25 +0300