国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【生成PDF】【JAVA】純后臺生成Echarts圖片,并將圖片生成到PDF文檔

這篇具有很好參考價值的文章主要介紹了【生成PDF】【JAVA】純后臺生成Echarts圖片,并將圖片生成到PDF文檔。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

前言

一、如何后臺生成Echarts圖片?

1.PhantomJS

2.PhantomJS的下載

?3.用phantomjs調(diào)用echarts-converts.js生成圖片

二、Java如何將Echarts圖生成到PDF

1.生成PDF依賴

2.Java代碼測試例子:

?3.測試結(jié)果?

?三、下載生成的PDF

ReportFormUtil


前言

提示:本文僅用于記錄日常,多有不足,僅供參考。

本次任務:要求不經(jīng)過web頁面,Java如何按月定時生成含有Echarts圖的PDF。

與我之前一篇文章中介紹的(Java如何根據(jù)前臺Echarts圖表生成PDF,并下載)區(qū)別在于,該文章中的Echarts圖片可以從已有的web頁面獲取,而本次任務沒有頁面。Echarts圖需要由后臺生成。那么整個流程分為以下三步:

1.如何后臺生成Echarts圖片?

2.Java如何將Echarts圖生成到PDF?

3.下載生成的PDF

本次任務重點在于第一點,只要后臺能生成Echarts圖片,生成PDF和下載文件的過程與前面文章中提到的方法差不多。


一、如何后臺生成Echarts圖片?

1.PhantomJS

后臺生成Echarts圖,需要使用到PhantomJS:一個自帶JavaScript API的無頭WebKit腳本,簡單理解就是:它能干瀏覽器能干的幾乎所有事情,能解析js、能渲染等等,但是沒有頁面讓你看。

2.PhantomJS的下載

https://phantomjs.org/api/fs/

http://wenku.kuryun.com/docs/phantomjs/index.html

也可以直接用我下載的文件:我的文件鏈接? 提取碼:es4e


打開我的文件:根據(jù)你使用的操作系統(tǒng),選擇一個進行下載并解壓。

echarts導出pdf,隨記,pdf,java,echarts?


?打開我的文件,除phantomjs文件外,可見還有一個文件夾echarts-convert,有2個文件:

1.echarts:里面是echarts和jquery,可以用你們自己本地或項目中的。

2.echarts-converts.js:是自己寫的js文件,用來渲染生成echarts圖片,可根據(jù)自己需求改寫。

echarts導出pdf,隨記,pdf,java,echarts?

注意:若使用自己本地的echarts和jquery文件,echarts-converts.js里面的文件路徑需要改寫,指向你的文件所在的位置。

echarts導出pdf,隨記,pdf,java,echarts


?3.用phantomjs調(diào)用echarts-converts.js生成圖片

以下以windows環(huán)境下舉例:?

1.從echarts官網(wǎng)隨便選擇一個圖,將option復制本地某個文件中(例:G:\test\testOption.txt)

2.手動創(chuàng)建一個空的png文件(例:G:\test\111.png)

echarts導出pdf,隨記,pdf,java,echarts? ? ????echarts導出pdf,隨記,pdf,java,echarts

3.cmd調(diào)用phantomjs進程,讓它去解析echarts-converts.js,并傳入一些參數(shù)(如圖):

G:\test\phantomjs-2.1.1-windows\bin\phantomjs.exe G:\test\echarts-convert\echarts-convert.js -txtPath G:\test\testOption.txt -picTmpPath G:\test\111.png -picPath G:\test\222.png

??echarts導出pdf,隨記,pdf,java,echartsecharts導出pdf,隨記,pdf,java,echarts

?

4.執(zhí)行完成,完成后,111.png圖片有內(nèi)容,且生成了一張222.png。

?echarts導出pdf,隨記,pdf,java,echarts


二、Java如何將Echarts圖生成到PDF

前面已經(jīng)可以通過手動調(diào)用的方式生成Echarts圖片。

接下來需要做的:

1、將手動生成圖片的過程通過代碼實現(xiàn)。

2、將生成的圖片生成出PDF

3、下載PDF

1.生成PDF依賴

<dependency>
   <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.3</version>
</dependency> 

2.Java代碼測試例子:

    public static void main(String[] args)
    {
        try
        {
            // 測試同時生成兩張圖
            // 注意:要先手動創(chuàng)建兩個空文件G:\\test\\1.png和G:\\test\\2.png;要提前將echarts的option數(shù)據(jù)寫到G:\\test\\testOption.txt和G:\\test\\testOption2.txt中
            doExecPhantomJS_deleteFileAfterException("G:\\test\\testOption.txt,G:\\test\\testOption2.txt", "G:\\test\\1.png,G:\\test\\2.png", "G:\\test\\111.png,G:\\test\\222.png");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        Paragraph ph1 = ReportFormUtil.createImageParagraphByPath("1、段落標題111", "G:\\test\\111.png", 35, 35,"這是一段前綴描述信息111", "這是一段后綴描述信息111");
        Paragraph ph2 = ReportFormUtil.createImageParagraphByPath("2、段落標題222", "G:\\test\\222.png", 35, 35, "這是一段前綴描述信息222", "這是一段后綴描述信息222");

        List<Paragraph> phs = new ArrayList<Paragraph>();
        phs.add(ph1);
        phs.add(ph2);

        ReportFormUtil.createPDFDocumentToDisk("封面名稱", "小標題", "", phs, "G:\\test\\document.pdf");
    }

?Tips:

一、ReportFormUtil文件放在文章結(jié)尾。

二、關(guān)于如何自動生成默認樣式的option.txt文件,不過多贅述:

我的主要做法是:option配置可以看成一個json格式的字符串,然后:

1、提供可配置的默認的option樣式;

2、將option中的數(shù)據(jù)部分(想自定義的部分)用符號占位;

3、在需要生成圖片時,結(jié)合業(yè)務計算出自定義數(shù)據(jù)并轉(zhuǎn)成json,替換掉占位符填到option字符串中生成完整的帶數(shù)據(jù)的option字符串。

4、將3中生成的完整option字符串寫到指定臨時txt文件中(流程結(jié)束后刪除臨時文件)

3.測試結(jié)果?

測試結(jié)果如圖所示:成功生成pdf文件,且生成了兩個圖片段落

echarts導出pdf,隨記,pdf,java,echarts


?三、下載生成的PDF

@Override
    public void download(HttpServletResponse response, HttpServletRequest request) throws BusinessException
    {

        // 選中的要導出的文檔id
        String id = request.getParameter("id");
        if (StringUtils.isBlank(id))
        {
            return;
        }

        // 1.根據(jù)id找出文檔信息
        DocumentTaskModel taskModel = documentTaskDao.findById(Integer.valueOf(id));

        // 2.下載
        File file = new File(taskModel.getUrl());// taskModel.getUrl():該PDF文件的存放路徑
        try (FileInputStream in = new FileInputStream(file); ServletOutputStream out = response.getOutputStream();)
        {
            // 若未定義文件名,則使用文檔配置中的默認文檔名
            String fileName = StringUtils.isNotBlank(taskModel.getName()) ? taskModel.getName()
                    : ReportFormEngine.getDocumentByKey(taskModel.getDocumentKey()).getName();

            response.reset();
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Length", "" + file.length());
            response.addHeader("Content-Disposition",
                    "attachment; filename=" + new String((fileName + ".pdf").getBytes("utf-8"), "iso8859-1"));

            byte[] buff = new byte[CommonConstants.BYTE_BUFFER_LENGTH_5120];
            int hasRead = -1;
            while ((hasRead = in.read(buff, 0, buff.length)) > 0)
            {
                out.write(buff, 0, hasRead);
            }
        }
        catch (FileNotFoundException e)
        {
            logger.error(e);
        }
        catch (IOException e)
        {
            logger.error(e);
        }
        catch (Exception e)
        {
            logger.error(taskModel.getUrl() + "下載文件失?。?, e);
        }
    }

ReportFormUtil

package com.smartsecuri.bp.cbb.reportform;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

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

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.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.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
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 com.smartsecuri.bp.cbb.exception.BusinessException;
import com.smartsecuri.bp.cbb.utils.file.FileUtils;
import com.smartsecuri.bp.cbb.utils.other.CommonUtils;
import com.smartsecuri.bp.cbb.utils.system.IoUtils;

/**
 * ClassName : ReportFormUtil <br/>
 * Function : (PDF文檔相關(guān)-主要用于生成報表) <br/>
 * date : 2022年11月29日 下午5:32:18 <br/>
 *
 * @author 
 * @version 
 * @since JDK 1.8
 */
public class ReportFormUtil
{
    private static final Logger logger = LogManager.getLogger(ReportFormUtil.class);

    /**
     * DEFAULT_LEADING : (默認行間距).
     */
    public static final float DEFAULT_LEADING = 16f;
    /**
     * fontSize_normal : (正文字體大小11號).
     */
    public static final float FONTSIZE_NORMAL = 11f;
    /**
     * fontSize_titile : (標題字體大小14號).
     */
    public static final float FONTSIZE_TITILE = 14f;
    /**
     * FONTSIZE_COVER : (封面字體大小32號).
     */
    public static final float FONTSIZE_COVER = 32f;

    /**
     * normalFont : (通用字體樣式:宋體、11號).
     */
    private static Font normalFont = null;
    /**
     * titleFont : (通用標題字體樣式:宋體、14號、加粗).
     */
    private static Font titleFont = null;
    /**
     * coverFont : (通用封面字體樣式:宋體、28號、加粗).
     */
    private static Font coverFont = null;

    // windows 測試環(huán)境
    private static final String phantomPath = "G:\\test\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe";
    private static final String JSpath = "G:\\test\\echarts-convert\\echarts-convert.js";

    // linux 環(huán)境
    // private static String phantomPath = "/usr/local/phantomjs/bin/phantomjs";
    // private static String JSpath = PathUtils.getProjectPath() + "common/reportform/echarts-convert.js";

    /**
     * getBaseFont : (獲取可以解析中文的字體:使用宋體). <br/>
     *
     * @author 
     * @return
     * @since JDK 1.8
     */
    public static BaseFont getBaseFontChinese()
    {
        try
        {
            // 宋體資源文件路徑
            URL path = ReportFormUtil.class.getResource("/config/fonts/simsun.ttc");
            return BaseFont.createFont(path + ",0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            // 本地main方法測試:使用windows自帶的宋體文件
            //return BaseFont.createFont("C://Windows//Fonts//simsun.ttc,0", BaseFont.IDENTITY_H, false);
        }
        catch (Exception e)
        {
            logger.error("設(shè)置字體樣式失敗", e);
            return null;
        }
    }

    /**
     * getNormalFont : (獲取普通正文字體樣式). <br/>
     *
     * @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 : (獲取標題通用字體). <br/>
     *
     * @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 : (獲取封面通用字體). <br/>
     *
     * @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;
    }


    /**
     * genFrontCover : (構(gòu)建封面的文字和樣式). <br/>
     *
     * @author 
     * @param coverName 封面標題
     * @param subtitle 小標題——封面標題下一行文字,可以為null或空串,表示不填
     * @param subscript 下標,可以為null或空串,表示不填
     * @return
     * @since JDK 1.8
     */
    public static Paragraph genFrontCover(String coverName, String subtitle, String subscript)
    {
        if (StringUtils.isBlank(coverName))
        {
            return null;
        }
        // 生成封面
        Paragraph frontCover = new Paragraph();
        frontCover.setAlignment(Element.ALIGN_CENTER);
        // 空10行
        ReportFormUtil.addBlankLine(frontCover, Integer.parseInt("10"));

        // 封面標題
        frontCover.add(new Chunk(coverName, ReportFormUtil.getCoverFontFont()));

        if (StringUtils.isNotBlank(subtitle))
        {
            ReportFormUtil.addBlankLine(frontCover, Integer.parseInt("2"));// 換行
            // 小標題
            frontCover.add(new Chunk(subtitle, ReportFormUtil.getTitleFont()));
        }

        if (StringUtils.isNotBlank(subscript))
        {
            // 換行
            ReportFormUtil.addBlankLine(frontCover, Integer.parseInt("25"));
            // companyName公司簽名如:"慧盾信息安全科技(蘇州)股份有限公司"
            frontCover.add(new Chunk(subscript, ReportFormUtil.getNormalFont()));
        }
        return frontCover;
    }

    /**
     * addBlankLine : (添加換行). <br/>
     *
     * @author 
     * @param paragraph 需要添加空行的段落
     * @param lineNum 需要添加空行的個數(shù)
     * @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);
        }
    }

    /**
     * createTable : (創(chuàng)建table段落). <br/>
     *
     * @author 
     * @param <T>
     * @param list 構(gòu)建table的數(shù)據(jù)
     * @param title 該段落取的名字,標題默認居左
     * @param methodNames 需要調(diào)用的方法名,用來獲取單元格數(shù)據(jù)。通常是某個屬性的get方法
     * @param prefixDescribe 前綴附加文字描述
     * @param suffixDescribe 后綴附加文字描述
     * @return
     * @since JDK 1.8
     */
    public static <T> Paragraph createTable(List<T> list, String title, String[] tableHead, String[] methodNames,
            String prefixDescribe, String suffixDescribe)
    {
        return createTable(list, FONTSIZE_NORMAL, FONTSIZE_TITILE, title, tableHead, methodNames,
                prefixDescribe, suffixDescribe);
    }

    /**
     * createTableByList : (創(chuàng)建table段落). <br/>
     *
     * @author 
     * @param <T>
     * @param listData 
     * @param normalFontSize 正文字體大小
     * @param titleFontSize 標題字體大小
     * @param title 段落名稱
     * @param methodNames 獲取表格屬性的方法名
     * @param prefixDescribe 前綴附加文字描述
     * @param suffixDescribe 后綴附加文字描述
     * @return
     * @since JDK 1.8
     */
    public static <T> Paragraph createTable(List<T> listData, float normalFontSize, float titleFontSize, String title,
            String[] tableHead, String[] methodNames, String prefixDescribe, String suffixDescribe)
    {

        // 1.創(chuàng)建一個表格
        PdfPTable table = new PdfPTable(methodNames.length);// 列數(shù)

        // 2.構(gòu)造表頭
        for (String head : tableHead)
        {
            head = StringUtils.isBlank(head) ? "" : head;
            PdfPCell cell = new PdfPCell(new Phrase(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);// 水平居中
            cell.setVerticalAlignment(Element.ALIGN_CENTER);// 垂直居中
            table.addCell(cell);
        }

        // 3.構(gòu)造table數(shù)據(jù)
        if (CollectionUtils.isEmpty(listData))
        {
            // 沒有數(shù)據(jù),添加一行空單元格,并返回
            for (int i = 0; i < methodNames.length; i++)
            {
                table.addCell(new Phrase(" "));// 有一個空格,否則添加不了
            }
        }
        else
        {
            // 有數(shù)據(jù):構(gòu)造table數(shù)據(jù)
            for (T li : listData)
            {
                for (String name : methodNames)
                {
                    Object obj = CommonUtils.invokeMethod(li, name);
                    String valueStr = obj == null ? " " : StringUtils.isEmpty(obj.toString()) ? " " : obj.toString();
                    PdfPCell cell = new PdfPCell(new Phrase(valueStr, getNormalFont()));
                    cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中
                    table.addCell(cell);
                }
            }
        }

        // 4.返回段落
        return createParagraph(table, title, prefixDescribe, suffixDescribe);
    }
    
    /**
     * addDataToTable : (從段落中找到table元素,向該table中追加數(shù)據(jù)). <br/>
     *
     * @author 
     * @param <T>
     * @param paragraph table表格段落
     * @param listData 需要追加的數(shù)據(jù)
     * @param methodNames 每個數(shù)據(jù)獲取的方法名
     * @since JDK 1.8
     */
    public static <T> void addDataToTable(Paragraph paragraph, List<T> listData, List<String> 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 = CommonUtils.invokeMethod(data, name).toString();
                    PdfPCell cell = new PdfPCell(new Phrase(valueStr, getNormalFont()));
                    cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 單元格文字水平居中
                    table.addCell(cell);
                }
            }
            break;
        }
    }

    /**
     * createImage : (根據(jù)圖片的base64加密文件創(chuàng)建pdf圖片段落). <br/>
     *
     * @author 
     * @param picBase64Info 傳入圖片的base64信息,或傳入前臺echart通過調(diào)用getDataURL()方法獲取的圖片信息都可以
     * @param title 段落標題
     * @param percentX 圖片縮放比例X軸
     * @param percentY 圖片縮放比例Y軸
     * @param prefixDescribe 前綴附加文字描述
     * @param suffixDescribe 后綴附加文字描述
     * 
     * @return 返回圖片段落
     * @since JDK 1.8
     */
    public static Paragraph createImageFromEncodeBase64(String picBase64Info, String title, float percentX,
            float percentY, String prefixDescribe, String suffixDescribe)
    {
        // 1.獲取圖片
        Element element = analysisPicBase64Info(picBase64Info);
        // 2.創(chuàng)建段落,并添加標題,設(shè)置縮放
        return createImageParagraph(element, title, percentX, percentY, prefixDescribe, suffixDescribe);
    }

    /**
     * createImageFromEncodeBase64_batch : (批量創(chuàng)建圖片段落). <br/>
     *
     * @author 
     * @param picBase64Infos 傳入圖片的base64信息,或傳入前臺echart通過調(diào)用getDataURL()方法獲取的圖片信息都可以
     * @param titles 每個段落的標題
     * @param percentXs X軸縮放比例
     * @param percentYs Y軸縮放比例
     * @param titleCenter 標題是否居中,true-居中、false-默認居左
     * @return 返回由多個圖片段落組合后的整個段落
     * @since JDK 1.8
     */
    public static Paragraph createImageFromEncodeBase64_batch(List<String> picBase64Infos, List<String> titles,
            List<Float> percentXs, List<Float> percentYs)
    {
        Paragraph paragraphs = new Paragraph(DEFAULT_LEADING);
        for (int i = 0; i <= picBase64Infos.size(); i++)
        {
            Paragraph imagePara = createImageFromEncodeBase64(picBase64Infos.get(i), titles.get(i), percentXs.get(i),
                    percentYs.get(i), null, null);
            if (!imagePara.isEmpty())
            {
                paragraphs.add(imagePara);
                // 換行
                paragraphs.add(Chunk.NEWLINE);
            }
        }
        return paragraphs;
    }

    /**
     * createPicParagraphByPath : (根據(jù)圖片位置生成圖片段落段落). <br/>
     *
     * @author 
     * @param title 段落標題
     * @param picPath 圖片所在磁盤路徑
     * @param percentX 圖片縮放比例X軸
     * @param percentY 圖片縮放比例Y軸
     * @param titleCenter 標題是否居中,true-居中、false-默認居左
     * @param prefixDescribe 前綴附加文字描述
     * @param suffixDescribe 后綴附加文字描述
     * @return
     * @since JDK 1.8
     */
    public static Paragraph createImageParagraphByPath(String title, String picPath, float percentX, float percentY,
            String prefixDescribe, String suffixDescribe)
    {
        // 1.獲取圖片
        Element element = analysisPicByPath(picPath);
        // 2.創(chuàng)建段落,并添加標題,設(shè)置縮放
        return createImageParagraph(element, title, percentX, percentY, prefixDescribe, suffixDescribe);
    }

    /**
     * createPicParagraphByPath : (根據(jù)圖片位置生成圖片段落段落). <br/>
     *
     * @author 
     * @param picElement 圖片元素
     * @param title 段落標題
     * @param percentX 圖片縮放比例X軸
     * @param percentY 圖片縮放比例Y軸
     * @param prefixDescribe 前綴附加文字描述
     * @param suffixDescribe 后綴附加文字描述
     * @return
     * @since JDK 1.8
     */
    public static Paragraph createImageParagraph(Element picElement, String title, float percentX, float percentY,
            String prefixDescribe, String suffixDescribe)
    {
        if (picElement == null)
        {
            return new Paragraph();
        }

        try
        {
            if (!(picElement instanceof Image))
            {
                // 1. 圖片解析失敗
                logger.error(title + ":picElement is not instanceof Image");
                return new Paragraph();
            }

            // 2.設(shè)置圖片縮放比例
            Image image = (Image) picElement;
            image.scalePercent(percentX, percentY);
            image.setAlignment(Element.ALIGN_CENTER);

            // 3.創(chuàng)建并返回圖片段落
            return createParagraph(image, title, prefixDescribe, suffixDescribe);
        }
        catch (Exception e)
        {
            logger.error(e);
            // 空段落
            return new Paragraph();
        }
    }

    /**
     * createTxtParagraph : (創(chuàng)建文本段落). <br/>
     *
     * @author 
     * @param strings 多行句子
     * @param title 段落標題
     * @param titleCenter 標題居中
     * @param prefixDescribe 前綴附加文字描述
     * @param suffixDescribe 后綴附加文字描述
     * @return
     * @since JDK 1.8
     */
    public static Paragraph createTxtParagraph(List<String> strings, String title, String prefixDescribe,
            String suffixDescribe)
    {
        Phrase phrase = new Phrase();
        for (String li : strings)
        {
            // 多行句子拼裝
            phrase.add(new Chunk(li, getNormalFont()));
            phrase.add(Chunk.NEWLINE);
        }

        return createParagraph(phrase, title, prefixDescribe, suffixDescribe);
    }

    /**
     * createParagraph : (根據(jù)元素創(chuàng)建段落). <br/>
     *
     * @author 
     * @param element
     * @param title 段落標題
     * @param prefixDescribe 前綴附加文字描述
     * @param suffixDescribe 后綴附加文字描述
     * @return
     * @since JDK 1.8
     */
    public static Paragraph createParagraph(Element element, String title, String prefixDescribe,
            String suffixDescribe)
    {
        title = StringUtils.isEmpty(title) ? "" : title;
        try
        {
            // 1.創(chuàng)建段落,并添加標題,添加前綴描述
            Paragraph paragraph = createParagraph(title, prefixDescribe);
            paragraph.add(element);

            // 2.后綴描述
            if (StringUtils.isNotBlank(suffixDescribe))
            {
                addBlankLine(paragraph, 1);// 換行符
                paragraph.add(new Paragraph(DEFAULT_LEADING, suffixDescribe, getNormalFont()));
            }
            return paragraph;
        }
        catch (Exception e)
        {
            logger.error(e);
            // 空段落
            return new Paragraph();
        }
    }

    /**
     * createParagraph : (創(chuàng)建段落). <br/>
     *
     * @author 
     * @param title
     * @param prefixDescribe 前綴附加文字描述
     * @return
     * @since JDK 1.8
     */
    public static Paragraph createParagraph(String title, String prefixDescribe)
    {
        Paragraph paragraph = new Paragraph(DEFAULT_LEADING);

        if (StringUtils.isNotEmpty(title))
        {
            paragraph.add(new Phrase(DEFAULT_LEADING, title, getTitleFont()));
            addBlankLine(paragraph, 2);
        }

        // 2.前綴描述
        if (StringUtils.isNotBlank(prefixDescribe))
        {
            paragraph.add(new Paragraph(prefixDescribe, getNormalFont()));
            ReportFormUtil.addBlankLine(paragraph, Integer.parseInt("1"));// 換行
        }

        return paragraph;
    }

    /**
     * createPDFDocument : (創(chuàng)建文檔,默認紙張大小A4). <br/>
     *
     * @author WuTingTing
     * @return
     * @since JDK 1.8
     */
    public static Document createPDFDocument()
    {
        return new Document(PageSize.A4, Float.parseFloat("36"), Float.parseFloat("36"), Float.parseFloat("36"),
                Float.parseFloat("36"));
    }

    /**
     * createPDFDocumentToDisk : (生成PDF文檔保存到磁盤). <br/>
     *
     * @author WuTingTing
     * @param coverName 封面標題
     * @param subtitle 小標題——封面標題下一行文字,可以為null或空串,表示不填
     * @param subscript 下標,可以為null或空串,表示不填
     * @param paragraphs 段落
     * @param documentPath 文件保存全路徑
     * @return
     * @since JDK 1.8
     */
    public static boolean createPDFDocumentToDisk(String coverName, String subtitle, String subscript,
            List<Paragraph> paragraphs, String documentPath)
    {
        // 1.創(chuàng)建文檔,設(shè)置文檔頁面大小,頁邊距
        Document document = createPDFDocument();
        // 2.封面
        Paragraph cover = genFrontCover(coverName, subtitle, subscript);

        // 3.生成文檔并保存到指定路徑
        return downloadDocument(document, cover, paragraphs, documentPath);
    }

    /**
     * exportDocument : (生成并下載PDF文檔-通過response響應實現(xiàn)下載). <br/>
     *
     * @author
     * @param document 文檔對象
     * @param cover 封面:若不是null,則會先添加封面,并另起新頁面添加段落;若是null表示沒有封面。
     * @param paragraphs 需要組成PDF文件的各個段落
     * @param response 請求的響應對象(提示:前臺無法通過ajax請求觸發(fā)瀏覽器的下載,可以通過表單提交的方式)
     * @param fileName 生成的文件名稱,不需要加pdf后綴
     * @since JDK 1.8
     */
    public static void exportDocument(Document document, Paragraph cover, List<Paragraph> paragraphs,
            HttpServletResponse response, String fileName)
    {
        try (ServletOutputStream out = response.getOutputStream())
        {
            response.setContentType("application/binary;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName + ".pdf", "UTF-8"));

            PdfWriter writer = PdfWriter.getInstance(document, out);
            writer.setStrictImageSequence(true);// 設(shè)置圖片位置精確放置
            // 1.打開文檔
            document.open();

            if (cover != null)
            {
                // 2.有封面:添加封面,并另起一頁,用來塞后面的段落
                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);
                }
                catch (DocumentException e)
                {
                    errorMsg.append("PDF文件生成出錯,請檢查第:").append(i).append("個段落");
                }
            }

            if (!StringUtils.isEmpty(errorMsg.toString()))
            {
                logger.error(errorMsg);
            }

            // 關(guān)閉文檔
            document.close();
            // 將數(shù)據(jù)輸出
            out.flush();
            out.close();
        }
        catch (IOException e)
        {
            logger.error("生成PDF文檔并下載,IOException:", e);
        }
        catch (DocumentException e)
        {
            logger.error("生成PDF文檔并下載,DocumentException:", e);
        }
        finally
        {
            document.close();
        }
    }

    /**
     * downloadDocument : (生成PDF文檔并保存到磁盤). <br/>
     *
     * @author 
     * @param document 文檔對象
     * @param cover 封面:若不是null,則會先添加封面,并另起新頁面添加段落
     * @param paragraphs 需要組成PDF文件的段落
     * @param response 請求的響應對象
     * @param fileName 生成的文件名稱,不需要加pdf后綴
     * @return true成功、false失敗
     * @since JDK 1.8
     */
    public static boolean downloadDocument(Document document, Paragraph cover, List<Paragraph> paragraphs,
            String documentPath)
    {
        FileOutputStream out = null;
        try
        {
            File file = new File(documentPath);
            if (!FileUtils.createFile(file))
            {
                return false;
            }

            out = new FileOutputStream(file);
            PdfWriter writer = PdfWriter.getInstance(document, out);
            writer.setStrictImageSequence(true);// 設(shè)置圖片位置精確放置

            // 打開文檔
            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);
                }
                catch (DocumentException e)
                {
                    errorMsg.append("PDF文件生成出錯,請檢查第:").append(i).append("個段落");
                }
            }

            if (!StringUtils.isBlank(errorMsg.toString()))
            {
                logger.error(errorMsg);
            }

            // 關(guān)閉文檔
            document.close();
            out.flush();
            IoUtils.close(out);
        }
        catch (Exception e)
        {
            logger.error("生成PDF文檔并下載,出錯:", e);
            return false;
        }
        finally
        {
            // 關(guān)閉文檔
            document.close();
            IoUtils.close(out);
        }
        return true;
    }

    /**
     * analysisPicBase64Info : (解析base64圖片信息). <br/>
     *
     * @author 
     * @param picBase64Info 傳入圖片的base64信息,或傳入前臺echart通過調(diào)用getDataURL()方法獲取的圖片信息都可以
     * @return 圖片經(jīng)過base64解碼后的信息
     * @since JDK 1.8
     */
    public static Element analysisPicBase64Info(String picBase64Info)
    {
        if (StringUtils.isEmpty(picBase64Info))
        {
            // 空段落
            return new Paragraph();
        }

        // 1.獲取圖片base64字符串信息:若入?yún)⑹峭ㄟ^前臺echarts調(diào)用getDataURL()方法獲取的,則該字符串包含逗號,且則逗號后面的內(nèi)容才是圖片的信息
        String pictureInfoStr = picBase64Info.indexOf(",") == -1 ? picBase64Info : picBase64Info.split(",")[1];
        // 2.將圖片信息進行base64解密
        byte[] imgByte = Base64.decodeBase64(pictureInfoStr);

        // 對異常的數(shù)據(jù)進行處理
        /**
         * .圖片的原始表達ascii碼范圍是0-255,
         * .這里面有一些不可見的編碼。然后為了圖片正確傳輸才轉(zhuǎn)成編碼base64的0-63,
         * .當從base64轉(zhuǎn)成byte時,byte的范圍是[-128,127],那么此時就會可能產(chǎn)生負數(shù),而負數(shù)不是在ascii的范圍里,所以需要轉(zhuǎn)換一下
         */
        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 : (根據(jù)圖片地址解析并生成圖片段落). <br/>
     *
     * @author 
     * @param picPath 圖片路徑
     * @return 
     * @since JDK 1.8
     */
    public static Element analysisPicByPath(String picPath)
    {
        if (StringUtils.isEmpty(picPath))
        {
            return null;// 空段落
        }

        File file = new File(picPath);
        if (!file.exists())
        {
            // 圖片文件不存在
            return null;// 空段落
        }

        try (FileInputStream in = new FileInputStream(file))
        {
            byte[] imgByte = new byte[(int) file.length()];
            in.read(imgByte);
            /**
             * .圖片的原始表達ascii碼范圍是0-255,
             * .這里面有一些不可見的編碼。然后為了圖片正確傳輸才轉(zhuǎn)成編碼base64的0-63,
             * .當從base64轉(zhuǎn)成byte時,byte的范圍是[-128,127],那么此時就會可能產(chǎn)生負數(shù),而負數(shù)不是在ascii的范圍里,所以需要轉(zhuǎn)換一下
             */
            for (int i = 0; i < imgByte.length; i++)
            {
                if (imgByte[i] < 0)
                {
                    imgByte[i] += 256;
                }
            }

            return Image.getInstance(imgByte);
        }
        catch (Exception e)
        {
            logger.error("analysisPicBase64Info error", e);
            return null;
        }
    }

    /**
     * analysisPicBase64Info_batch : (批量解析base64加密的圖片信息,生成Image對象). <br/>
     *
     * @author 
     * @param picBase64Infos 傳入圖片的base64信息,或傳入前臺echart通過調(diào)用getDataURL()方法獲取的圖片信息都可以
     * @return
     * @since JDK 1.8
     */
    public static List<Element> analysisPicBase64Info_batch(List<String> picBase64Infos)
    {
        List<Element> images = new ArrayList<Element>();
        for (String li : picBase64Infos)
        {
            Element image = analysisPicBase64Info(li);
            images.add(image);
        }
        return images;
    }

    /**
     * doExecPhantomJS_deleteFileAfterException : (執(zhí)行:瀏覽器加載option,渲染并截圖保存到制定文件,若過程中出現(xiàn)錯誤則刪除picTmpPath、picPath中生成的文件). <br/>
     * .【注意】支持一次多個,多個時路徑以逗號隔開,且jsonPath和picPath的個數(shù)要一致。
     */
    public static void doExecPhantomJS_deleteFileAfterException(String txtPath, String picTmpPath, String picPath)
            throws BusinessException, Exception
    {
        doExecPhantomJS_deleteFileAfterException(txtPath, picTmpPath, picPath, null, null);
    }
    
    /**
     * doExecPhantomJS_deleteFileAfterException : (執(zhí)行:瀏覽器加載option,渲染并截圖保存到制定文件,若過程中出現(xiàn)錯誤則刪除picTmpPath、picPath中生成的文件). <br/>
     * .【注意】支持一次多個,多個時路徑以逗號隔開,且jsonPath和picPath的個數(shù)要一致。
     * .單個例子:
     * txtPath="/a/a.json"
     * picTmpPath="/a/tmp/a.png"
     * picPath="/a/a.png"
     * width=1000
     * height=600
     * 
     * .多個例子:
     * txtPath="/a/a.txt,/b/b.json,/c/c.txt"
     * picTmpPath="/a/tmp/a.png,/b/tmp/b.png,/c/tmp/c.png"
     * picPath="/a/a.png,/b/b.png,/c/c.png"
     * width=1000,1000,1000
     * height=600,600,600,600
     *
     * @author WuTingTing
     * @param txtPath 圖表option信息的txt文件全路徑
     * @param picTmpPath 圖片臨時存放路徑,生成后將轉(zhuǎn)移到picPath路徑下
     * @param picPath 圖片文件全路徑
     * @param width 自定義截圖寬度
     * @param height 自定義截圖高度
     * @throws Exception 
     * @since JDK 1.8
     */
    public static void doExecPhantomJS_deleteFileAfterException(String txtPath, String picTmpPath, String picPath,
            String width, String height) throws BusinessException, Exception
    {
        try
        {
            doExecPhantomJS(txtPath, picTmpPath, picPath, width, height);
        }
        catch (Exception e)
        {
            // 執(zhí)行過程中出錯,刪除本次執(zhí)行中可能生成的文件,不刪除txtPath是防止該文件為默認內(nèi)置文件
            String[] picTmpPaths = picTmpPath.split(",");
            String[] picPaths = picPath.split(",");

            for (String li : picTmpPaths)
            {
                FileUtils.delFile(li);
            }

            for (String li : picPaths)
            {
                FileUtils.delFile(li);
            }

            if (e instanceof BusinessException)
            {
                logger.error(((BusinessException) e).getMsg());
                throw new BusinessException().setMsg(((BusinessException) e).getMsg());
            }
            else
            {
                throw new Exception(e);
            }
        }
    }

    /**
     * doExecPhantomJS : (執(zhí)行:瀏覽器加載option,渲染并截圖保存到制定文件). <br/>
     * .【注意】支持一次多個,多個時路徑以逗號隔開,且jsonPath和picPath的個數(shù)要一致。
     * .單個例子:
     * txtPath="/a/a.json"
     * picTmpPath="/a/tmp/a.png"
     * picPath="/a/a.png"
     * 
     * .多個例子:
     * txtPath="/a/a.txt,/b/b.json,/c/c.txt"
     * picTmpPath="/a/tmp/a.png,/b/tmp/b.png,/c/tmp/c.png"
     * picPath="/a/a.png,/b/b.png,/c/c.png"
     *
     * @author WuTingTing
     * @param txtPath 圖表option信息的txt文件全路徑
     * @param picTmpPath 圖片臨時存放路徑,生成后將轉(zhuǎn)移到picPath路徑下
     * @param picPath 圖片文件全路徑
     * @throws Exception 
     * @since JDK 1.8
     */
    private static void doExecPhantomJS(String txtPath, String picTmpPath, String picPath, String width, String height)
            throws BusinessException, Exception
    {
        String cmd = getCMD(txtPath, picTmpPath, picPath, width, height);
        logger.info("圖片生成命令:" + cmd);

        BufferedReader processInput = null;

        // 檢查文件是否存在
        boolean existP = FileUtils.fileExists(phantomPath);
        boolean existJ = FileUtils.fileExists(JSpath);
        if (!existP || !existJ)
        {
            throw new BusinessException()
                    .setMsg("生成圖片必要文件缺失:" + (!existP ? "phantomjs " : "") + (!existJ ? "echarts-convert.js、" : ""));
        }

        try
        {
            Process process = Runtime.getRuntime().exec(cmd);
            processInput = new BufferedReader(
                    new InputStreamReader(process.getInputStream(), Charset.forName("UTF-8")));
            String line = "";
            while ((line = processInput.readLine()) != null)
            {
                // 執(zhí)行信息打印
                logger.info(line);
            }
            int waitFor = process.waitFor();
            if (waitFor != 0)
            {
                logger.info("圖片生成過程,非正常退出,請檢查是否存在異常");
            }
        }
        finally
        {
            if (processInput != null)
            {
                try
                {
                    processInput.close();
                }
                catch (IOException e)
                {
                    logger.error("io close fail");
                }
            }
        }
    }

    /**
     * getCMD : (拼接命令). <br/>
     *
     * @author 
     * @param txtPath 圖表option信息的txt文件全路徑
     * @param picTmpPath 圖片臨時存放路徑,生成后將轉(zhuǎn)移到picPath路徑下
     * @param picPath 圖片文件全路徑
     * @param width 自定義截圖寬度
     * @param height 自定義截圖高度
     * @return
     * @throws BusinessException
     * @since JDK 1.8
     */
    private static String getCMD(String txtPath, String picTmpPath, String picPath, String width, String height)
            throws BusinessException
    {
        if (StringUtils.isBlank(txtPath) || StringUtils.isBlank(picTmpPath) || StringUtils.isBlank(picPath))
        {
            logger.error("txtPath or picTmpPath or picPath is blank");
            throw new BusinessException().setMsg("doExecPhantomJS 入?yún)㈠e誤");
        }

        if (StringUtils.isNotBlank(width) && StringUtils.isNotBlank(height))
        {
            return phantomPath + " " + JSpath + " -txtPath " + txtPath + " -picTmpPath " + picTmpPath + " -picPath "
                    + picPath + " -width " + width + " -height " + height;
        }
        else
        {
            // 未自定義截圖寬度和高度,會使用默認寬、高
            return phantomPath + " " + JSpath + " -txtPath " + txtPath + " -picTmpPath " + picTmpPath + " -picPath "
                    + picPath;
        }
    }

    public static void main(String[] args)
    {
        try
        {
            // 測試同時生成兩張圖
            // 注意:要先手動創(chuàng)建兩個空文件G:\\test\\1.png和G:\\test\\2.png;要提前將echarts的option數(shù)據(jù)寫到G:\\test\\testOption.txt和G:\\test\\testOption2.txt中
            doExecPhantomJS_deleteFileAfterException("G:\\test\\testOption.txt,G:\\test\\testOption2.txt", "G:\\test\\1.png,G:\\test\\2.png", "G:\\test\\111.png,G:\\test\\222.png");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        Paragraph ph1 = ReportFormUtil.createImageParagraphByPath("1、段落標題111", "G:\\test\\111.png", 35, 35,"這是一段前綴描述信息111", "這是一段后綴描述信息111");
        Paragraph ph2 = ReportFormUtil.createImageParagraphByPath("2、段落標題222", "G:\\test\\222.png", 35, 35, "這是一段前綴描述信息222", "這是一段后綴描述信息222");

        List<Paragraph> phs = new ArrayList<Paragraph>();
        phs.add(ph1);
        phs.add(ph2);

        ReportFormUtil.createPDFDocumentToDisk("封面名稱", "小標題", "", phs, "G:\\test\\document.pdf");
    }
}

注意:

我自己嘗試后發(fā)現(xiàn),phantomJS調(diào)用的js里面若用了一些較新的語法,phantomJS是不支持的,例如:const、let、=>、帶默認值的函數(shù)function test( a=1,b=[] ){} 、文章來源地址http://www.zghlxwxcb.cn/news/detail-698539.html

到了這里,關(guān)于【生成PDF】【JAVA】純后臺生成Echarts圖片,并將圖片生成到PDF文檔的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • echarts文檔解讀

    echarts文檔解讀

    前言:今天給大家分享一個前端的開源可視化圖標庫echarts。 ??點擊下方名片,即可領(lǐng)取學長個人微信?? 全局 echarts 對象,在 script 標簽引入? echarts.js ?文件后獲得,或者在 AMD 環(huán)境中通過? require(\\\'echarts\\\') ?獲得。 所有屬性 echarts.?init Function 創(chuàng)建一個 ECharts 實例,返回?e

    2024年02月02日
    瀏覽(27)
  • 【vue后臺管理系統(tǒng)】基于Vue+Element-UI+ECharts開發(fā)通用管理后臺(中)

    【vue后臺管理系統(tǒng)】基于Vue+Element-UI+ECharts開發(fā)通用管理后臺(中)

    點擊菜單圖標之前: 點擊菜單圖標之后: 首先我們要知道菜單欄的收縮,由el-menu的collapse屬性控制: 我們通過分析可以知道: 菜單按鈕的點擊是在CommonHeader.vue組件中,而我們修改的collapse屬性卻在CommonAside.vue中,這是兩個不同的組件。很明顯這涉及到了組件間的通信問題,

    2024年02月03日
    瀏覽(62)
  • Spire.PDF for .NET【文檔操作】演示:動態(tài)創(chuàng)建 PDF 并將其發(fā)送到客戶端瀏覽器

    Spire.PDF for .NET【文檔操作】演示:動態(tài)創(chuàng)建 PDF 并將其發(fā)送到客戶端瀏覽器

    可移植文檔格式 (PDF) 是 Adobe 制定的獨立規(guī)范的固定版式文檔。它封裝了完整的描述,包括文本字體、圖形和顯示它所需的其他信息。 Spire.PDF for .NET?是一款獨立 PDF 控件,用于 .NET 程序中創(chuàng)建、編輯和操作 PDF 文檔。使用 Spire.PDF 類庫,開發(fā)人員可以新建一個 PDF 文檔或者對現(xiàn)

    2024年04月25日
    瀏覽(26)
  • Java word文檔轉(zhuǎn)圖片 || word轉(zhuǎn)pdf兩行代碼搞定

    Java word文檔轉(zhuǎn)圖片 || word轉(zhuǎn)pdf兩行代碼搞定

    目錄 一、首先引入我們需要的依賴。 二、準備一個word文檔模板,使用{{}}定義我們需要填充的數(shù)據(jù)。 三、word文檔動態(tài)數(shù)據(jù)填充轉(zhuǎn)換圖片demo示例 四、poi-tl(poi template language)Word模板引擎 五、把demo示例簡化封裝成Controller接口層 六、word文檔生成動態(tài)數(shù)據(jù)轉(zhuǎn)換成pdf 一、首先引

    2024年02月06日
    瀏覽(30)
  • echarts官網(wǎng)文檔打開慢的解決方法

    由于我們在做大數(shù)據(jù)屏的時候需要很多echarts圖表,這個過程中也會遇到需要查詢echarts官網(wǎng)文檔、手冊、配置項的時候,但是由于網(wǎng)站在國外,訪問很慢或者打不開。 針對上面的問題我們可以通過訪問echarts網(wǎng)站國內(nèi)鏡像來加速訪問。 echarts網(wǎng)站國內(nèi)鏡像:https://www.isqqw.com/ec

    2024年02月12日
    瀏覽(22)
  • Java 生成各種 PDF 實戰(zhàn)方案(圖片、模板、表格)

    Java 生成各種 PDF 實戰(zhàn)方案(圖片、模板、表格)

    本篇文章的重點還是在講通過java生成pdf,其實如果是單純的模板填充挺簡單的,但是又要填充模板還要動態(tài)生成表格就比較麻煩了,因為如果在模板中畫表格的框去生成的話,超過模板框的位置就會隱藏,我剛接到需求的時候也是有點難受,在網(wǎng)上也是找了大量的資料,研究

    2024年02月02日
    瀏覽(23)
  • Java根據(jù)word模板生成word文檔并轉(zhuǎn)成PDF文件

    Java根據(jù)word模板生成word文檔并轉(zhuǎn)成PDF文件

    定義完我們的模板之后,我們要將文檔保存為xml的格式 生成的xml格式看起來比較亂,沒有層次感, 所以需要格式化一下 格式化 基礎(chǔ)信息的定義 基礎(chǔ)信息的定義只要保證我們轉(zhuǎn)化成的xml文件中的${name}等格式?jīng)]錯誤即可 表格的定義 遍歷實現(xiàn),表格的數(shù)據(jù)填充 在xml文件中我們的

    2024年02月09日
    瀏覽(35)
  • Java將獲取的參數(shù),圖片以及pdf文件放入到word文檔指定位置

    Java將獲取的參數(shù),圖片以及pdf文件放入到word文檔指定位置

    首先引入的依賴 接下面的是template.docx文檔,參數(shù)是以{{paramName}}格式的,為什么要以這種格式,是因為下面的方法,在替換參數(shù)的時候需要 但是從數(shù)據(jù)庫獲取的參數(shù)跟模板中的參數(shù)一一對應上即可,格式如下(我是json形式展示的): { ?? ?\\\"countQuota\\\": \\\"1\\\", ?? ?\\\"noEmission\\\": \\\"1\\\", ?

    2024年02月15日
    瀏覽(34)
  • 【Java】制作pdf模板使用后端程序填充字段生成pdf或者圖片

    【Java】制作pdf模板使用后端程序填充字段生成pdf或者圖片

    自行下載安裝; 打開pdf文件,表單-添加或編輯域 添加文本域,調(diào)整大小,可以編輯域的名字,默認fill_1這種名字。域鼠標右鍵-屬性,可以調(diào)整字體大小等樣式,編輯好還可以鎖定; 編輯好保存,這個pdf文件就可以當模板使用了; 防止中文亂碼,需要在網(wǎng)上下載字體ttf文件

    2024年01月21日
    瀏覽(26)
  • Java中Itext生成Pdf,并給PdfCell添加圖片

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包