欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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)文章

  • mybatis映射和實(shí)際類型不一致的問題

    mybatis映射和實(shí)際類型不一致的問題

    這篇文章主要介紹了mybatis映射和實(shí)際類型不一致的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Spring Boot快速實(shí)現(xiàn) IP地址解析的示例詳解

    Spring Boot快速實(shí)現(xiàn) IP地址解析的示例詳解

    這篇文章主要介紹了Spring Boot快速實(shí)現(xiàn)IP地址解析,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • Springboot項(xiàng)目引入druid安裝部署使用教程

    Springboot項(xiàng)目引入druid安裝部署使用教程

    這篇文章主要介紹了Springboot項(xiàng)目引入druid安裝部署使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • 使用Java實(shí)現(xiàn)文件夾的遍歷操作指南

    使用Java實(shí)現(xiàn)文件夾的遍歷操作指南

    網(wǎng)上大多采用java遞歸的方式遍歷文件夾下的文件,這里我不太喜歡遞歸的風(fēng)格,這篇文章主要給大家介紹了關(guān)于使用Java實(shí)現(xiàn)文件夾的遍歷操作的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Java UrlRewriter偽靜態(tài)技術(shù)運(yùn)用深入分析

    Java UrlRewriter偽靜態(tài)技術(shù)運(yùn)用深入分析

    通常我們?yōu)榱烁玫木徑夥?wù)器壓力,和增強(qiáng)搜索引擎的友好面,都將文章內(nèi)容生成靜態(tài)頁面,這就產(chǎn)生了偽靜態(tài)技術(shù),也就是我們常說的Url Rewriter重寫技術(shù)
    2012-12-12
  • mybatis resultType自帶數(shù)據(jù)類型別名解讀

    mybatis resultType自帶數(shù)據(jù)類型別名解讀

    MyBatis為了簡(jiǎn)化開發(fā),通過org.apache.ibatis.type.TypeAliasRegistry為常見類定義了別名,這些別名包括基本數(shù)據(jù)類型及其數(shù)組、集合類型等,如string對(duì)應(yīng)java.lang.String,int對(duì)應(yīng)java.lang.Integer等,此外,還有特殊前綴的別名如_int對(duì)應(yīng)int類型
    2024-10-10
  • java自動(dòng)生成接口文檔完整代碼示例

    java自動(dòng)生成接口文檔完整代碼示例

    在軟件開發(fā)中,編寫接口文檔是一項(xiàng)必要但繁瑣的任務(wù),為了簡(jiǎn)化這一過程,可以通過使用Swagger2和Swagger-UI來自動(dòng)生成接口文檔,這篇文章主要介紹了java自動(dòng)生成接口文檔的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • Java面向接口編程之命令模式實(shí)例詳解

    Java面向接口編程之命令模式實(shí)例詳解

    這篇文章主要介紹了Java面向接口編程之命令模式,結(jié)合實(shí)例形式詳細(xì)分析了Java面向接口編程命令模式的定義、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • idea批量啟動(dòng)多個(gè)微服務(wù)具體實(shí)現(xiàn)

    idea批量啟動(dòng)多個(gè)微服務(wù)具體實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于idea批量啟動(dòng)多個(gè)微服務(wù)的具體實(shí)現(xiàn),在微服務(wù)開發(fā)過程中,我們經(jīng)常要在本地啟動(dòng)很多個(gè)微服務(wù),文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • springbean的八種加載方式匯總

    springbean的八種加載方式匯總

    這篇文章主要介紹了springbean的八種加載方式,一種是XML方式聲明bean,使用@Component及其衍生注解@Controller?、@Service、@Repository定義bean,還有其他方法,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10

最新評(píng)論