Java使用POI-TL實現(xiàn)生成有個性的簡歷
1.介紹
POI-TL 是一個基于 Apache POI 的 Java 庫,專注于在 Microsoft Word 文檔(.docx 格式)中進(jìn)行模板填充和動態(tài)內(nèi)容生成。它的全稱是 “POI Template Language”,旨在簡化文檔生成過程,特別是在需要根據(jù)動態(tài)數(shù)據(jù)生成復(fù)雜文檔的場景中。POI-TL 通過提供一種簡單而強大的模板引擎,使開發(fā)者能夠輕松地將數(shù)據(jù)嵌入到 Word 文檔中,從而自動化生成報告、合同、發(fā)票等文檔。
2.原理
POI-TL 的核心原理是將 Word 文檔視為模板,并在其中定義占位符。占位符通常以 {{key}}
的形式出現(xiàn),代表需要動態(tài)替換的內(nèi)容。開發(fā)者通過 Java 代碼提供一個數(shù)據(jù)模型,其中包含占位符對應(yīng)的實際值。POI-TL 使用這些數(shù)據(jù)來替換模板中的占位符,從而生成最終的文檔。
POI-TL 基于 Apache POI 構(gòu)建,利用 POI 提供的對 Word 文檔的低級別操作能力,實現(xiàn)了對文檔的高效處理。它支持復(fù)雜的文檔結(jié)構(gòu),包括表格、圖片、段落等,使得生成的文檔不僅內(nèi)容準(zhǔn)確,還能保持良好的格式和樣式。
3.代碼工程
目標(biāo)
利用word模版生成簡歷
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>Java-demo</artifactId> <groupId>com.et</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>poi-tl</artifactId> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.2</version> </dependency> <!-- Log4j dependencies for logging --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.19.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.19.0</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency> </dependencies> </project>
模版
在代碼倉庫的測試包下面
src/test/resources/resume.docx
代碼
ExperienceData.java
package com.et; import com.deepoove.poi.data.NumberingRenderData; public class ExperienceData { private String company; private String department; private String time; private String position; private NumberingRenderData responsibility; public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } public NumberingRenderData getResponsibility() { return responsibility; } public void setResponsibility(NumberingRenderData responsibility) { this.responsibility = responsibility; } }
ResumeDataV2.java
package com.et; import java.util.List; import com.deepoove.poi.data.NumberingRenderData; import com.deepoove.poi.data.PictureRenderData; public class ResumeDataV2 { private PictureRenderData portrait; private String name; private String job; private String sex; private String phone; private String birthday; private String province; private String email; private String address; private String english; private String University; private String rank; private String education; private String profession; private NumberingRenderData stack; private String hobbies; private List<ExperienceData> experiences; public void setPortrait(PictureRenderData portrait) { this.portrait = portrait; } public PictureRenderData getPortrait() { return this.portrait; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setJob(String job) { this.job = job; } public String getJob() { return this.job; } public void setSex(String sex) { this.sex = sex; } public String getSex() { return this.sex; } public void setPhone(String phone) { this.phone = phone; } public String getPhone() { return this.phone; } public void setBirthday(String birthday) { this.birthday = birthday; } public String getBirthday() { return this.birthday; } public void setProvince(String province) { this.province = province; } public String getProvince() { return this.province; } public void setEmail(String email) { this.email = email; } public String getEmail() { return this.email; } public void setAddress(String address) { this.address = address; } public String getAddress() { return this.address; } public void setEnglish(String english) { this.english = english; } public String getEnglish() { return this.english; } public void setUniversity(String University) { this.University = University; } public String getUniversity() { return this.University; } public void setRank(String rank) { this.rank = rank; } public String getRank() { return this.rank; } public void setEducation(String education) { this.education = education; } public String getEducation() { return this.education; } public void setProfession(String profession) { this.profession = profession; } public String getProfession() { return this.profession; } public void setStack(NumberingRenderData stack) { this.stack = stack; } public NumberingRenderData getStack() { return this.stack; } public void setHobbies(String hobbies) { this.hobbies = hobbies; } public String getHobbies() { return this.hobbies; } public List<ExperienceData> getExperiences() { return experiences; } public void setExperiences(List<ExperienceData> experiences) { this.experiences = experiences; } }
ResumeIterableExample.java
package com.et; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.data.Numberings; import com.deepoove.poi.data.Pictures; import com.deepoove.poi.data.TextRenderData; import com.deepoove.poi.data.style.Style; @DisplayName("Foreach resume example") public class ResumeIterableExample { ResumeDataV2 datas = new ResumeDataV2(); @BeforeEach public void init() { datas.setPortrait(Pictures.ofLocal("src/test/resources/sayi.png").size(100, 100).create()); datas.setName("卅一"); datas.setJob("BUG工程師"); datas.setPhone("18080809090"); datas.setSex("男"); datas.setProvince("杭州"); datas.setBirthday("2000.08.19"); datas.setEmail("adasai90@gmail.com"); datas.setAddress("浙江省杭州市西湖區(qū)古蕩1號"); datas.setEnglish("CET6 620"); datas.setUniversity("美國斯坦福大學(xué)"); datas.setProfession("生命工程"); datas.setEducation("學(xué)士"); datas.setRank("班級排名 1/36"); datas.setHobbies("音樂、畫畫、乒乓球、旅游、讀書\nhttps://github.com/Sayi"); // 技術(shù)棧部分 TextRenderData textRenderData = new TextRenderData("SpringBoot、SprigCloud、Mybatis"); Style style = Style.builder().buildFontSize(10).buildColor("7F7F7F").buildFontFamily("微軟雅黑").build(); textRenderData.setStyle(style); datas.setStack(Numberings.of(textRenderData, textRenderData, textRenderData).create()); /* * {{?experiences}} {{company}} {{department}} {{time}} {{position}} * {{*responsibility}} {{/experiences}} */ List<ExperienceData> experiences = new ArrayList<ExperienceData>(); ExperienceData data0 = new ExperienceData(); data0.setCompany("香港微軟"); data0.setDepartment("Office 事業(yè)部"); data0.setTime("2001.07-2020.06"); data0.setPosition("BUG工程師"); textRenderData = new TextRenderData("負(fù)責(zé)生產(chǎn)BUG,然后修復(fù)BUG,同時有效實施招聘行為"); textRenderData.setStyle(style); data0.setResponsibility(Numberings.of(textRenderData, textRenderData).create()); ExperienceData data1 = new ExperienceData(); data1.setCompany("自由職業(yè)"); data1.setDepartment("OpenSource 項目組"); data1.setTime("2015.07-2020.06"); data1.setPosition("研發(fā)工程師"); textRenderData = new TextRenderData("開源項目的迭代和維護(hù)工作"); textRenderData.setStyle(style); TextRenderData textRenderData1 = new TextRenderData("持續(xù)集成、Swagger文檔等工具調(diào)研"); textRenderData1.setStyle(style); data1.setResponsibility(Numberings.of(textRenderData, textRenderData1, textRenderData).create()); experiences.add(data0); experiences.add(data1); experiences.add(data0); experiences.add(data1); datas.setExperiences(experiences); } @Test public void testResumeExample() throws Exception { XWPFTemplate template = XWPFTemplate.compile("src/test/resources/resume.docx").render(datas); FileOutputStream out = new FileOutputStream("target/out_example_resume_iterable.docx"); template.write(out); out.flush(); out.close(); template.close(); } }
以上只是一些關(guān)鍵代碼,所有代碼請參見下面代碼倉庫
代碼倉庫
github.com/Harries/Java-demo(POI-TL )
4.測試
運行測試代碼,打開生成的文件(target/out_example_resume_iterable.docx)如下圖展示
以上就是Java使用POI-TL實現(xiàn)生成有個性的簡歷的詳細(xì)內(nèi)容,更多關(guān)于Java POI-TL生成簡歷的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot中@ControllerAdvice注解的使用方法
這篇文章主要介紹了SpringBoot中@ControllerAdvice注解的使用方法,這是一個增強的?Controller,對controller層做異常處理、數(shù)據(jù)預(yù)處理、全局?jǐn)?shù)據(jù)綁定,?springboot?會自動掃描到,不需要調(diào)用,這個注解是spring?MVC提供的,在springboot中也可以使用,需要的朋友可以參考下2024-01-01SpringBoot+netty-socketio實現(xiàn)服務(wù)器端消息推送
這篇文章主要介紹了SpringBoot+netty-socketio實現(xiàn)服務(wù)器端消息推送,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Java實現(xiàn)數(shù)據(jù)庫連接池簡易教程
這篇文章主要為大家介紹了Java實現(xiàn)數(shù)據(jù)庫連接池簡易教程,感興趣的小伙伴們可以參考一下2016-01-01Spring的自定義擴展標(biāo)簽NamespaceHandler解析
這篇文章主要介紹了Spring的自定義擴展標(biāo)簽NamespaceHandler解析,在很多情況下,我們需要為系統(tǒng)提供可配置化支持,簡單的做法可以直接基于Spring的標(biāo)準(zhǔn)Bean來配置,Spring提供了可擴展Schema的支持,這是一個不錯的折中方案,需要的朋友可以參考下2023-12-12