最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java導(dǎo)出pdf文件的詳細(xì)實(shí)現(xiàn)方法

 更新時(shí)間:2025年03月15日 10:55:02   作者:lmxnsI  
這篇文章主要介紹了java導(dǎo)出pdf文件的詳細(xì)實(shí)現(xiàn)方法,包括制作模板、獲取中文字體文件、實(shí)現(xiàn)后端服務(wù)以及前端發(fā)起請(qǐng)求并生成下載鏈接,需要的朋友可以參考下

使用注意點(diǎn)

因?yàn)樵瓉碇谱鞯膒df表單內(nèi)容過于復(fù)雜,下面代碼只包含前兩行的操作。

本次操作需要前端向后端發(fā)起請(qǐng)求,后端返回?cái)?shù)據(jù)給前端用于下載,所以沒有在本地進(jìn)行保存。

第 1 步制作pdf模板需要的pdf編輯軟件基本上都需要錢,可以去買一個(gè)

第 2 步獲取的pdf導(dǎo)出的中文需要的文件,如果pdf輸出的內(nèi)容有中文就需要去弄一下這個(gè)文件,在代碼中用于讀取設(shè)置中文字體

包含內(nèi)容

1、導(dǎo)出pdf

2、設(shè)置斜體水印

1、制作pdf模板

先將需要的pdf模板通過word制作出來,然后導(dǎo)出為pdf

使用Adobe Acrobat DC 打開并制作模板(其他pdf編輯軟件也可以)

選擇打開前面導(dǎo)出的pdf模板

點(diǎn)擊準(zhǔn)備表單

點(diǎn)擊之后,可以針對(duì)沒一個(gè)位置進(jìn)行編輯,選中雙擊就可以進(jìn)行編輯了,要注意,每個(gè)位置的名字都需要是唯一的

全部賦值后保存即可

2、獲取pdf導(dǎo)出中文需要的文件

獲取中文字體需要的文件

在電腦這個(gè)路徑下選擇下載一個(gè)就行

3、實(shí)現(xiàn)

pom依賴

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.2.3</version>
    <type>pom</type>
</dependency>

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.24</version>
</dependency>

controller接口

    @GetMapping("/exportPDF/{applyId}")
    public ResponseEntity<byte[]> exportPDF(@PathVariable("applyId") String applyId, HttpServletResponse response) throws IOException,ParseException,Exception {

        byte[] res = applyService.exportPDF(applyId);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment; filename=filled_form.pdf");
        headers.add("Content-Type", "application/pdf");

        return ResponseEntity.ok()
                .headers(headers)
                .body(res);
    }

service具體實(shí)現(xiàn)

	public static byte[] exportPDF1() throws Exception {
        String inputTemplateName = "template";
        try {
            pdfBytes = null;
            Map<String, String> map = new HashMap<>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            // map預(yù)填數(shù)據(jù),用于后面讀取輸出到pdf文件上
            map.put("department-1", "研發(fā)中心");
            map.put("submitDate-1", sdf.format(new Date()));
            map.put("submitPerson-1", "張三");
            map.put("travelPerson-1", "李四");
            map.put("receivePerson-1","王五");

            // 設(shè)置中文字體
            PdfFont chineseFont = PdfFontFactory.createFont("src/main/resources/file/simsun.ttc,0");

            // 模板路徑
            String templatePath = "src\\main\\resources\\file\\" + inputTemplateName + ".pdf";

            // 重點(diǎn),這一個(gè)關(guān)聯(lián)了reader 和 writer
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

            // 讀取文件
            FileInputStream pdfInputStream = new FileInputStream(new File(templatePath));
            // 定義 reader 和writer
            PdfReader reader = new PdfReader(pdfInputStream);
            PdfWriter writer = new PdfWriter(byteArrayOutputStream,new WriterProperties().setStandardEncryption(
                    null,
                    null,
                    EncryptionConstants.ALLOW_PRINTING, // 允許打印
                    EncryptionConstants.ENCRYPTION_AES_128 // 加密方式
            ));

            // 根據(jù) reader 和writer 創(chuàng)建 PdfDocument
            PdfDocument pdfDocument = new PdfDocument(reader,writer);

            // 下面是給文件添加水印,不需要的可以直接刪掉
            // 獲取 pdf 模板頁數(shù)
            int numberOfPages = pdfDocument.getNumberOfPages();

            // 遍歷每一頁并添加水印
            for (int i = 1; i <= numberOfPages; i++) {
                PdfPage page = pdfDocument.getPage(i);

                // 獲取頁面尺寸(在這里我沒有用)
                int pageWidth = (int) Math.floor(page.getPageSize().getWidth());
                int pageHeight = (int) Math.floor(page.getPageSize().getHeight());

                // 創(chuàng)建一個(gè) PdfCanvas 對(duì)象
                PdfCanvas canvas = new PdfCanvas(page);

                // 保存當(dāng)前坐標(biāo)系狀態(tài)
                canvas.saveState();

                // 水印內(nèi)容旋轉(zhuǎn)
                double angle = Math.toRadians(45);
                double cos = Math.cos(angle);
                double sin = Math.sin(angle);
                canvas.concatMatrix(cos, sin, -sin, cos, 0, 0);

                // 設(shè)置水印的字體和透明度
                canvas.setFontAndSize(PdfFontFactory.createFont(), 20);
                canvas.setFillColorRgb(0.75f, 0.75f, 0.75f);  // 灰色
                canvas.setLineWidth(2);

                // 正常應(yīng)該根據(jù)獲取到的頁面尺寸進(jìn)行 x y 軸的遍歷并
                // 但是我這邊沒有鋪滿,就自己設(shè)置了遍歷的范圍
                for (int x = -90; x < 2000; x += 300) {
                    for (int y = -190; y < 2000; y += 200) {
                        // 繪制水印文字
                        canvas.beginText();
                        canvas.setTextMatrix(x, y);  // 設(shè)置水印位置
                        canvas.showText("Watermark Text this is just a test");  // 水印文字內(nèi)容
                        canvas.endText();
                    }
                }

                // 恢復(fù)坐標(biāo)系狀態(tài)
                canvas.restoreState();

            }

            // form 可以理解為把pdf文件看做一個(gè)form表單,以key value鍵值對(duì)保存
            PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDocument, true);

            // 遍歷上面預(yù)填的 map 并將值根據(jù) key 賦值到form
            for (Map.Entry<String, String> entry : map.entrySet()) {
                form.getField(entry.getKey()).setValue(entry.getValue());
                form.getField(entry.getKey()).setFont(chineseFont).setFontSize(8);
            }
            pdfDocument.close();
            // 返回文件流
            pdfBytes = byteArrayOutputStream.toByteArray();

            return pdfBytes;

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            return pdfBytes;
        }
    }

4、前端發(fā)起請(qǐng)求并生成下載鏈接

	exportPdf(applyId) {
      exportPDF(applyId).then(res => {
        // 創(chuàng)建一個(gè) Blob 對(duì)象,指定類型為 PDF 文件
        const blob = new Blob([res.data], { type: 'application/pdf' });

        // 創(chuàng)建一個(gè) URL 對(duì)象,指向 Blob 數(shù)據(jù)
        const url = URL.createObjectURL(blob);

        // 創(chuàng)建一個(gè)下載鏈接
        const link = document.createElement('a');
        link.href = url;
        link.download = 'generated_with_form.pdf'; // 設(shè)置下載文件名

        // 模擬點(diǎn)擊下載鏈接
        link.click();

        // 下載完成后釋放 URL 對(duì)象
        URL.revokeObjectURL(url);
      })
    },

總結(jié) 

到此這篇關(guān)于java導(dǎo)出pdf文件的詳細(xì)實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)java導(dǎo)出pdf文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java利用POI讀取excel文件的方法

    java利用POI讀取excel文件的方法

    這篇文章主要介紹了java利用POI讀取excel文件的方法,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-12-12
  • Java多線程——之一創(chuàng)建線程的四種方法

    Java多線程——之一創(chuàng)建線程的四種方法

    這篇文章主要介紹了Java創(chuàng)建線程方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 將本地服務(wù)注冊(cè)到nacos上的實(shí)現(xiàn)過程

    將本地服務(wù)注冊(cè)到nacos上的實(shí)現(xiàn)過程

    文章介紹了如何在本地安裝和啟動(dòng)Nacos服務(wù),并配置本地應(yīng)用程序使用Nacos進(jìn)行服務(wù)注冊(cè),文章強(qiáng)調(diào)了啟動(dòng)日志窗口的重要性,并提供了一個(gè)簡(jiǎn)短的總結(jié),希望對(duì)讀者有所幫助
    2026-01-01
  • Java輸出打印工具類封裝的實(shí)例

    Java輸出打印工具類封裝的實(shí)例

    下面小編就為大家?guī)硪黄狫ava輸出打印工具類封裝的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • MyBatis實(shí)現(xiàn)多表聯(lián)合查詢r(jià)esultType的返回值

    MyBatis實(shí)現(xiàn)多表聯(lián)合查詢r(jià)esultType的返回值

    這篇文章主要介紹了MyBatis多表聯(lián)合查詢r(jià)esultType的返回值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java對(duì)象深復(fù)制與淺復(fù)制實(shí)例詳解

    Java對(duì)象深復(fù)制與淺復(fù)制實(shí)例詳解

    這篇文章主要介紹了 Java對(duì)象深復(fù)制與淺復(fù)制實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 從繁瑣到簡(jiǎn)潔的Jenkins?Pipeline腳本優(yōu)化實(shí)踐

    從繁瑣到簡(jiǎn)潔的Jenkins?Pipeline腳本優(yōu)化實(shí)踐

    這篇文章主要為大家介紹了從繁瑣到簡(jiǎn)潔的Jenkins?Pipeline腳本優(yōu)化實(shí)踐示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Java詳細(xì)分析講解泛型

    Java詳細(xì)分析講解泛型

    在正式進(jìn)入內(nèi)容之前說明一下:泛型的內(nèi)容太多,也太復(fù)雜。這里因?yàn)镴ava中寫數(shù)據(jù)結(jié)構(gòu)的時(shí)候會(huì)使用到,所以加上。關(guān)于泛型我找了挺多文章,再結(jié)合自己的理解,盡可能將其講清楚。不求會(huì)使用泛型,只要求后面數(shù)據(jù)結(jié)構(gòu)出現(xiàn)泛型的時(shí)候能夠知道是在干什么即可
    2022-05-05
  • java中對(duì)象轉(zhuǎn)json字符串的三種常用方式

    java中對(duì)象轉(zhuǎn)json字符串的三種常用方式

    本文主要介紹了java中對(duì)象轉(zhuǎn)json字符串的三種常用方式,包含Jackson庫,Gson庫和Hutool工具類這三種,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • 你知道Java的這些騷操作嗎?

    你知道Java的這些騷操作嗎?

    今天在看python相關(guān)的東西,看到各種騷操作,回頭想了下Java有沒有什么騷操作,整理下面幾種,一起看一下吧,需要的朋友可以參考下
    2021-05-05

最新評(píng)論

通海县| 金华市| 南召县| 西平县| 东乌珠穆沁旗| 金堂县| 来宾市| 禹城市| 古交市| 金塔县| 冕宁县| 泰宁县| 视频| 垦利县| 怀化市| 哈巴河县| 庆元县| 彰化县| 中江县| 台中市| 南汇区| 陇川县| 乡宁县| 敖汉旗| 许昌县| 建瓯市| 潼南县| 漾濞| 吉林省| 峡江县| 宜君县| 车致| 泰顺县| 高要市| 龙口市| 攀枝花市| 吉安市| 辽阳县| 桐梓县| 黄骅市| 平顶山市|