JAVA 使用IText7 + Freemarker 动态数据生成PDF实现案例
技术方案:IText7 + Freemarker
技术文档
- Itext 官网:https://itextpdf.com/
- itext API文档:https://api.itextpdf.com/iText7/java/7.1.14/
- FreeMarker API文档:英文:https://freemarker.apache.org/docs/index.html ;中文:http://freemarker.foofun.cn/ref_builtins_loop_var.html
- CSS 文档:https://www.runoob.com/css/css-tutorial.html
- HTML文档:https://www.runoob.com/html/html-tutorial.html
使用maven导入相关依赖
<properties>
<itext.version>7.1.15</itext.version>
</properties>
<dependencies>
<!-- itext7 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>io</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>forms</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>pdfa</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>pdftest</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>font-asian</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.18</version>
</dependency>
<!--itext7 html转pdf用到的包-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
</dependencies>
实现方案
- 配置Freemarker引擎
首先,我们需要配置Freemarker引擎,指定模板文件所在的路径并设置默认编码。我们可以使用以下代码来完成配置:
Configuration config = new Configuration(Configuration.getVersion());
config.setTemplateLoader(new ClassTemplateLoader(PdfGenerator.class, templatesPath)); config.setDefaultEncoding("UTF-8");
这里的templatesPath变量表示我们存放模板文件的相对路径。由于我们是在Java中运行程序,所以要使用ClassTemplateLoader类来加载模板文件。
- 加载模板文件并填充数据
一旦我们配置好了Freemarker引擎,就可以加载模板文件并将要填充的数据传递给它。可以使用以下代码来完成这一步骤:
Template template = config.getTemplate(templatesName);
StringWriter out = new StringWriter();
template.process(data, out); out.flush();
这里的templatesName变量表示我们要加载的模板文件的名称。数据通过process方法传递给模板引擎,填充模板并生成HTML代码。
- 将HTML代码转换为PDF文件
一旦我们有了HTML代码,就可以使用IText7将其转换为PDF文件。使用以下代码将HTML代码转换为PDF文件:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(outputStream);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf, PageSize.A4);
document.setMargins(2, 4, 2, 2);
FontSet fontSet = new FontSet();
fontSet.addFont(fontsPath);
FontProvider fontProvider = new FontProvider(fontSet);
ConverterProperties converterProps = new ConverterProperties(); converterProps.setFontProvider(fontProvider);
HtmlConverter.convertToPdf(htmlContent, pdf, converterProps);
pdf.close();
byte[] bytes = outputStream.toByteArray();
这里的fontsPath变量表示我们使用的中文字体的路径。我们使用了IText7提供的HtmlConverter类来将HTML代码转换为PDF文件,并将字体设置为中文字体。
在完成上述步骤后,我们便能够成功实现使用IText7和Freemarker引擎生成PDF文件的功能。
附工具类完成代码
import com.alibaba.fastjson.JSONObject;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.font.FontProvider;
import com.itextpdf.layout.font.FontSet;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* @date: 2023年5月23日, 0023 下午 08:21
* @version: 1.0.0
* @Description:PDF工具类
* @Time: 2023-05-23 20:21
*/
public class PdfGenerator {
private static final String templatesPath = "/templates/";
private static final String fontsPath = "/fonts/simhei.ttf";
private static final String templatesName = "template.html";
/**
* 使用Freemarker引擎加载HTML模板文件并填充变量值,并将HTML字符串转换为PDF文件
*
* @param data 模板要填充的数据
* @throws Exception
*/
public static byte[] generatePDF(Map<String, Object> data) throws Exception {
Configuration config = new Configuration(Configuration.getVersion());
// 设置Freemarker引擎的模板路径
config.setTemplateLoader(new ClassTemplateLoader(PdfGenerator.class, templatesPath));
config.setDefaultEncoding("UTF-8");
Template template = config.getTemplate(templatesName);
StringWriter out = new StringWriter();
template.process(data, out);
out.flush();
// 使用Freemarker引擎加载HTML模板文件并填充变量值
String htmlContent = out.toString();
byte[] bytes = convertHtmlToPdf(htmlContent);
return bytes;
}
/**
* 使用iText 7将HTML字符串转换为PDF文件,并返回PDF文件的二进制数据
*
* @param htmlString 待转换的HTML字符串
* @return 返回生成的PDF文件内容
* @throws IOException
*/
private static byte[] convertHtmlToPdf(String htmlString) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(outputStream);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf, PageSize.A4);
// 设置左、右、上、下四个边距的值,以点(pt)为单位
document.setMargins(2, 4, 2, 2);
// 设置中文字体
FontSet fontSet = new FontSet();
fontSet.addFont(fontsPath);
FontProvider fontProvider = new FontProvider(fontSet);
ConverterProperties converterProps = new ConverterProperties();
converterProps.setFontProvider(fontProvider);
// 调用HtmlConverter类的convertToPdf函数,将HTML字符串转换为PDF文件
HtmlConverter.convertToPdf(htmlString, pdf, converterProps);
pdf.close();
// 将PDF文件转换为字节数组并返回
return outputStream.toByteArray();
}
}
注:templatesPath,fontsPath,templatesName在src/main/resources下
附HTML模板文件代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
@page {
size: A4;
margin: 5mm 10mm; /* 上下和左右两个方向的边距分别为 10mm 和 20mm */
}
body {
width: 180mm;
height: 297mm;
}
.item_content {
width: 95%;
height: 100%;
}
.item_content .title {
overflow: hidden; /* 清除浮动 */
box-sizing: border-box; /* 盒模型以边框为界计算宽度 */
display: flex;
height: 20pt;
width: 100%;
align-items: center;
justify-content: center;
}
.item_content .title .circle {
float: left;
width: 3%;
padding-right: 0.5px; /* 右侧间距 */
align-self: center;
justify-self: center;
margin-right: -1pt;
margin-top: 2pt;
}
.item_content .title .title_text {
float: left;
width: 12%;
color: #409EFF;
text-align: center;
position: relative;
font-size: 15pt;
padding-right: 0.5px; /* 右侧间距 */
align-self: center;
justify-self: center;
}
.item_content .title .line {
float: right;
width: 85%;
border-top: 0.75pt solid black;
margin-top: 10pt;
}
.item_content .section {
overflow: hidden; /* 清除浮动 */
box-sizing: border-box; /* 盒模型以边框为界计算宽度 */
display: flex;
height: 100%; /* 高度设为100% */
margin: auto;
}
.item_content .section .section_photo {
float: left;
width: 14.5%;
text-align: center;
}
.item_content .section .section_info {
float: right;
width: 84.5%;
align-self: center;
justify-self: center;
text-align: left;
}
.item_content .section .section_info .name {
color: #409EFF;
font-size: 21pt;
}
.item_content .section .section_info .address {
width: 100%;
height: 40px;
line-height: 40px;
background: #5195db;
color: white;
font-size: 15pt;
padding: 0 15pt;
margin: 10px 0 0;
-webkit-print-color-adjust: exact;
}
.item_content .section .section_info .divider {
width: 100%;
margin: 15pt 0;
border-top: 0.75pt solid #ccc;
}
.item_content .section .section_info .info-container {
overflow: hidden;/* 清除浮动后的高度问题 */
margin-top: 1%;
margin-bottom: 1%;
font-size: 11.25pt;
gap: 4%;
}
.item_content .section .section_info .info-container .left-container{
float: left;
width: 48%;
mmargin-top: 1%;
margin-bottom: 1%;
}
.item_content .section .section_info .info-container .right-container{
float: right;
width: 48%;
margin-top: 1%;
margin-bottom: 1%;
}
.item_content .section .section_info .info-container .left-container .id-card-photo-container{
overflow: hidden;/* 清除浮动后的高度问题 */
}
.item_content .section .section_info .info-container .left-container .id-card-photo-container .left-id-card-photo{
float: left;
width: 40%;/* 左半部分的宽度为 40% */
}
.item_content .section .section_info .info-container .left-container .id-card-photo-container .right-id-card-photo{
float: right;
width: 60%;/* 右半部分的宽度为 60% */
}
.item_content .section .section_info .record-container {
overflow: hidden;/* 清除浮动后的高度问题 */
margin-top: 1%;
margin-bottom: 1%;
font-size: 11.25pt;
gap: 4%;
}
.item_content .section .section_info .record-container .left-record {
float: left;
width: 48%;/* 左半部分的宽度为 50% */
mmargin-top: 1%;
margin-bottom: 1%;
text-align: left;
}
.item_content .section .section_info .record-container .right-record {
float: right;
width: 48%;/* 右半部分的宽度为 50% */
margin-top: 1%;
margin-bottom: 1%;
text-align: left;
}
.item_content .experience {
width: 90%;
margin: 15px auto 20px;
background: #f5f5f5;
-webkit-print-color-adjust: exact;
padding: 10px 20px;
}
.item_content .experience .experience-info{
overflow: hidden;/* 清除浮动后的高度问题 */
font-size: 11.25pt;
}
.item_content .experience .experience-info .left-experience{
float: left; /* 左浮动 */
width: 33.33%; /* 固定宽度 */
box-sizing: border-box; /* 盒模型以边框为界计算宽度 */
padding-right: 7.5pt; /* 右侧间距 */
text-align: left;
}
.item_content .experience .experience-info .middle-experience{
float: left; /* 左浮动 */
width: 33.33%; /* 固定宽度 */
box-sizing: border-box; /* 盒模型以边框为界计算宽度 */
padding-right: 7.5px; /* 右侧间距 */
text-align: left;
}
.item_content .experience .experience-info .right-experience{
float: left; /* 左浮动 */
width: 33.33%; /* 固定宽度 */
box-sizing: border-box; /* 盒模型以边框为界计算宽度 */
text-align: left;
}
.item_content .table_style {
border-collapse: collapse;
width: 100%;
}
.item_content .table_style td {
text-align: center;
height: 11.25pt;
padding: 3.75pt 7.5pt;
min-width: 97.5pt;
max-width: none;
}
.item_content .table_style thead td {
font-weight: 600;
background: #f3f3f3;
font-size: 11.25pt;
}
.item_content .table_style thead th {
font-weight: 600;
background: #f3f3f3;
font-size: 13pt;
}
</style>
</head>
<body style="text-align: center">
<div>
<div>
<div class="scroll-show">
<div style="margin-right:3%;margin-left:5%;">
<div class="item_content">
<div class="title">
<div class="circle"><img src="https://egongban.oss-cn-shenzhen.aliyuncs.com/2023/05/29/b506e8108f4d9ee742370f4301e170a.png" style="width: 14pt; height: 14pt;"></div>
<div class="title_text">个人信息</div>
<div class="line"></div>
</div>
<div class="section">
<div class="section_photo">
<#if projectWorker.avatarUrl?has_content>
<#assign imgUrl = projectWorker.avatarUrl>
<#assign imgAlt = "Image description">
<img src="${imgUrl}" alt="${imgAlt}"
style="width: 75pt; height: 75pt;margin-top: 110pt;"></img>
</#if>
</div>
<div class="section_info">
<div class="name">${projectWorker.name}</div>
<div class="address">所属省市:${projectWorker.address}</div>
<div class="info-container">
<div class="left-container">
<div class="id-card-photo-container">
<div class="left-id-card-photo">身份证照片:</div>
<div class="right-id-card-photo">
<#if projectWorker.idCardFrontUrl?has_content>
<#assign imgUrl = projectWorker.idCardFrontUrl>
<#assign imgAlt = "Image description">
<img src="${imgUrl}" alt="${imgAlt}"
style="width: 37.5pt; height: 37.5pt;margin-right: 3.75pt;">
</#if>
<#if projectWorker.idCardBackUrl?has_content>
<#assign imgUrl = projectWorker.idCardBackUrl>
<#assign imgAlt = "Image description">
<img src="${imgUrl}" alt="${imgAlt}"
style="width: 37.5pt; height: 37.5pt;">
</#if>
</div>
</div>
<div>姓名:${projectWorker.name}</div>
<div>性别:<#if projectWorker.gender?has_content>${projectWorker.gender}</#if></div>
<div>民族:<#if projectWorker.nationality?has_content>${projectWorker.nationality}</#if></div>
<div>身份证有效日期:<#if projectWorker.dateIssue?has_content && projectWorker.expiryDate?has_content>${projectWorker.dateIssue?substring(0, 10)} — ${projectWorker.expiryDate?substring(0, 10)}</#if></div>
</div>
<div class="right-container">
<div style="height: 37.5pt">身份证:<#if projectWorker.idCard?has_content>${projectWorker.idCard}</#if></div>
<div>年龄:<#if projectWorker.age?has_content>${projectWorker.age}</#if></div>
<div>住址:<#if projectWorker.address?has_content>${projectWorker.address}</#if></div>
<div>发证机关:<#if projectWorker.issuingAuthority?has_content>${projectWorker.issuingAuthority}</#if></div>
</div>
</div>
<div class="divider"></div>
<div class="info-container">
<div class="left-container">
<div>联系电话:<#if projectWorker.phone?has_content>${projectWorker.phone}</#if></div>
<div>家庭电话:<#if projectWorker.familyPhone?has_content>${projectWorker.familyPhone}</#if></div>
<div>微信号码:<#if projectWorker.wechat?has_content>${projectWorker.wechat}</#if></div>
<div>联系地址:<#if projectWorker.contactAddress?has_content>${projectWorker.contactAddress}</#if></div>
</div>
<div class="right-container">
<div>工人工种:<#if projectWorker.workTypeName?has_content>${projectWorker.workTypeName}</#if></div>
<div>紧急联系人:<#if projectWorker.emergencyContactPerson?has_content>${projectWorker.emergencyContactPerson}</#if></div>
<div>紧急联系人关系:<#if projectWorker.emergencyContactRelation?has_content>${projectWorker.emergencyContactRelation}</#if></div>
<div>紧急联系人电话:<#if projectWorker.emergencyContactPhone?has_content>${projectWorker.emergencyContactPhone}</#if></div>
</div>
</div>
<div class="divider"></div>
<div class="record-container">
<#if (projectWorker.projectWorkerBankCardList?has_content && projectWorker.projectWorkerBankCardList?size > 0)>
<#list projectWorker.projectWorkerBankCardList as record>
<#if record?index % 2 == 0>
<div class="left-record">
<div>工资银行卡:${record.bankName}</div>
<div>工资卡开户支行:${record.branchBankName}</div>
<div>工资卡卡号:${record.bankCard}</div>
</div>
<#else>
<div class="right-record">
<div>工资银行卡:${record.bankName}</div>
<div>工资卡开户支行:${record.branchBankName}</div>
<div>工资卡卡号:${record.bankCard}</div>
</div>
</#if>
</#list>
</#if>
</div>
<div class="divider"></div>
<div class="info-container">
<div class="left-container">
<div>政治面貌:<#if projectWorker.politicalAffiliationName?has_content>${projectWorker.politicalAffiliationName}</#if></div>
<div>文化水平:<#if projectWorker.educationalLevelName?has_content>${projectWorker.educationalLevelName}</#if></div>
<div>是否服兵役:<#if projectWorker.militaryService?has_content>${projectWorker.militaryService?string('是', '否')}</#if></div>
<div>服役时间:<#if projectWorker.enlistmentBeginTime?has_content && projectWorker.enlistmentEndTime?has_content>${projectWorker.enlistmentBeginTime?substring(0, 10)} — ${projectWorker.enlistmentEndTime?substring(0, 10)}</#if></div>
<div>婚姻状况:<#if projectWorker.maritalStatus?has_content>${projectWorker.maritalStatus?string('已婚', '未婚')}</#if></div>
<div>家庭成员:<#if projectWorker.familyMember?has_content>${projectWorker.familyMember}</#if></div>
<div>从业时间:<#if projectWorker.employmentBeginTime?has_content && projectWorker.employmentEndTime?has_content>${projectWorker.employmentBeginTime?substring(0, 10)} — ${projectWorker.employmentEndTime?substring(0, 10)}</#if></div>
</div>
<div class="right-container">
<div>专业技能:<#if projectWorker.professionalSkill?has_content>${projectWorker.professionalSkill}</#if></div>
<div>专业证书:
<#if projectWorker.emergencyContactPerson?has_content>
${projectWorker.emergencyContactPerson}
</#if>
</div>
<div>有无困难:<#if projectWorker.difficulty?has_content>${projectWorker.difficulty}</#if></div>
<div>对企业的希望:<#if projectWorker.enterpriseExpectation?has_content>${projectWorker.enterpriseExpectation}</#if></div>
<div>对自身的职业规划:<#if projectWorker.oneselfOccupationalPlan?has_content>${projectWorker.oneselfOccupationalPlan}</#if></div>
</div>
</div>
</div>
</div>
<div class="title">
<div class="circle"><img src="https://egongban.oss-cn-shenzhen.aliyuncs.com/2023/05/29/b506e8108f4d9ee742370f4301e170a.png" style="width: 14pt; height: 14pt;"></div>
<div class="title_text" id="experience">从业经历</div>
<div class="line"></div>
</div>
<div class="experience">
<#if (workingExperienceList?has_content && workingExperienceList?size> 0)>
<#list workingExperienceList as record>
<#if record?has_content>
<div class="experience-info">
<div class="left-experience">
<div>项目名称:<#if record.projectName?has_content>${record.projectName}</#if></div>
<div>合同名称:<#if record.contractName?has_content>${record.contractName}</#if></div>
<div>合伙项名称:<#if record.contractItemName?has_content>${record.contractItemName}</#if></div>
<div>项目工种:<#if record.workTypeName?has_content>${record.workTypeName}</#if></div>
<div>评分:<#if record.score?has_content>${record.score}</#if></div>
<#if (record.userAEvalRecordsVo?has_content)>
<#list record.userAEvalRecordsVo as vo>
<#if vo?has_content && (vo?index == 0 || vo?index % 3 == 0)>
<div>${vo.indicatorName}: ${vo.avgScore}</div>
</#if>
</#list>
</#if>
</div>
<div class="middle-experience">
<div>所属公司:<#if record.companyName?has_content>${record.companyName}</#if></div>
<div>所属小组:<#if record.teamName?has_content>${record.teamName}</#if></div>
<div>记工方式:<#if record.payTypeName?has_content>${record.payTypeName}</#if></div>
<div>进场日期:<#if record.approachTime?has_content>${record.approachTime}</#if></div>
<br>
<#if (record.userAEvalRecordsVo?has_content)>
<#list record.userAEvalRecordsVo as vo>
<#if vo?has_content && (vo?index == 1 || vo?index % 3 == 1)>
<div>${vo.indicatorName}: ${vo.avgScore}</div>
</#if>
</#list>
</#if>
</div>
<div class="right-experience">
<div>退场日期:<#if record.exitTime?has_content>${record.exitTime}</#if></div>
<div>角色:<#if record.workerTypeName?has_content>${record.workerTypeName}</#if><#if record.partnerTypeName?has_content>${record.partnerTypeName}</#if></div>
<br>
<br>
<br>
<#if (record.userAEvalRecordsVo?has_content)>
<#list record.userAEvalRecordsVo as vo>
<#if vo?has_content && (vo?index == 2 || vo?index % 3 == 2)>
<div>${vo.indicatorName}: ${vo.avgScore}</div>
</#if>
</#list>
</#if>
</div>
</div>
</#if>
</#list>
</#if>
</div>
<div class="title">
<div class="circle"><img src="https://egongban.oss-cn-shenzhen.aliyuncs.com/2023/05/29/b506e8108f4d9ee742370f4301e170a.png" style="width: 14pt; height: 14pt;"></div>
<div class="title_text" id="training">安全培训</div>
<div class="line"></div>
</div>
<div style="width: 90%;margin: 15px auto;">
<table class="table_style">
<thead>
<tr>
<th style="width: 33%;">培训视频</th>
<th style="width: 33%;">状态</th>
<th style="width: 33%;">观看日期</th>
</tr>
</thead>
<tbody>
<#if (workerTrainingRecordList?has_content)>
<#list workerTrainingRecordList as record>
<#if record?has_content>
<tr>
<td>
<#if record.title?has_content>${record.title}</#if>
</td>
<td>
<#if record.statusName?has_content>${record.statusName}</#if>
</td>
<td>
<#if record.date?has_content>${record.date}</#if>
</td>
</tr>
</#if>
</#list>
</#if>
</tbody>
</table>
</div>
<div class="title">
<div class="circle"><img src="https://egongban.oss-cn-shenzhen.aliyuncs.com/2023/05/29/b506e8108f4d9ee742370f4301e170a.png" style="width: 14pt; height: 14pt;"></div>
<div class="title_text" id="record">奖惩记录</div>
<div class="line"></div>
</div>
<div style="width: 90%;margin: 15px auto;">
<table class="table_style">
<thead>
<tr>
<th style="width: 25%;font-size: 16px;">项目名称</th>
<th style="width: 25%;">类型</th>
<th style="width: 25%;">金额</th>
<th style="width: 25%;">备注</th>
</tr>
</thead>
<tbody>
<#if (workerRewardPunishRecordList?has_content)>
<#list workerRewardPunishRecordList as record>
<#if record?has_content>
<tr>
<td>
<#if record.projectName??>${record.projectName}</#if>
</td>
<td>
<#if record.typeName??>${record.typeName}</#if>
</td>
<td>
<#if record.amount??>${record.amount}</#if>
</td>
<td>
<#if record.remark??>${record.remark}</#if>
</td>
</tr>
</#if>
</#list>
</#if>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
JAVA 使用IText7 + Freemarker 动态数据生成PDF实现案例的更多相关文章
- Java操作Jxl实现导出数据生成Excel表格数据文件
实现:前台用的框架是Easyui+Bootstrap结合使用,需要引入相应的Js.Css文件.页面:Jsp.拦截请求:Servlet.逻辑处理:ClassBean.数据库:SQLserver. 注意: ...
- ASP.NET 将数据生成PDF (二)
可以下载itextsharp(https://sourceforge.net/projects/itextsharp)下载,然后在工程中引用该控件,举例子如下 1 datatable 的内容转换为P ...
- swiper轮播问题之一:轮播图内容为动态数据生成时轮播图无法自动轮播
本人在用H5做移动端项目中使用Swiper遇到的两个问题,因此加深了对Swiper的掌握,分享出来对刚开始接触Swiper的童鞋们或多或少会有帮助. 首先,new Swiper的初始化最 ...
- C#应用NPOI实现导出EXcel表格中插入饼状图(可实现动态数据生成)
一.思路: 1.excel是可以通过NPOI插入图片的: 2.C#通过NPOI生成饼状图: 3.把生成的饼状图以字节流的形式插入到表格 二.看代码: #region 生成饼图图例 /// < ...
- Python数据生成pdf文件
sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...
- C#简单实现动态数据生成Word文档并保存
今天正好有人问我,怎么生成一个报表式的Word文档. 就是文字的样式和位置相对固定不变,只是里面的内容从数据中读取. 我觉得类似这种的一般用第三方报表来做比较简便.但既然要求了Word,只好硬着头皮来 ...
- java代码操作word模板并生成PDF
这个博客自己现在没时间写,等后面有时间了,自己再写. 这中需求是在实际的项目开发中是会经常遇到的. 下面我们先从简单入手一步一步开始. 1.首先,使用word创建一个6行两列的表格. 点击插入-6行2 ...
- java实现点击查询数据生成excel文件并下载
须先导入关键maven包 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi& ...
- [itext]Java生成PDF文件
一.前言 最近在做也导出试卷的功能,刚开始是导出为doc,可是导出来格式都有变化,最后说直接将word转为pdf,可是各种不稳定,各种报错.最后想到直接将文件写入pdf(参考:http://www.c ...
- Spring Boot集成JasperReports生成PDF文档
由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲染生成PDF文档.本人文采欠缺,写作能力 ...
随机推荐
- IDEA配置JDK版本的地方, 适用于Compilation failed: internal java compiler error
错误原因: 1. 编译版本不匹配 2.当前项目jdk版本不支持 解决方法 查看项目的jdk 查看工程的jdk 查看java编译器版本 讲这些改成自己需要的版本, 一般就可以解决编译版本出现的错误
- 几个对js帮助挺多的大佬写的博客
深入理解javascript原型和闭包(完结) JavaScript系列文章 同步异步回调DEMO知乎大佬的this与new解释 宏任务与微任务解析 js闭包 Vue项目中技巧ts学习 ES6基础入门 ...
- vue之写发表评论思路
后端接口 var express = require('express'); const sql = require('../sql') const Comment = require('../sql ...
- GitLab服务器傻瓜式搭建教程
开始前的准备 需要有一台Linux系统的服务器或虚拟机 QAQ 安装包下载地址:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ 注* 本教程无需下载安装 ...
- 一道名题-(csp 儒略日)的心得与技巧
引: 如果你见到一个oi对着 4713,1582 146097 2299160 颠颠地笑,不用怀疑,他是在做那道名题--<csp-s2020 T1 儒略日> 这道题,我做了三年,平均每年做 ...
- 列表、sort、reverse、元组、字典、
1.列表是一种有序可变的容器.通过[]来标识 1)定义一个空列表list = [] 2.列表的添加 1)末尾添加append() list = ['张三',,'王五'] list.append('刘六 ...
- ZR.Admin小改和VUE3版本体验
前言 孔乙己显出极高兴的样子,将两个指头的长指甲敲着柜台,点头说:"对呀,对呀!......回字有四样写法,你知道么?" 大家好,我是44岁的大龄程序员码农阿峰.阿峰从事编程二十年 ...
- Redis源码之SDS简单动态字符串
Redis 是内存数据库,高效使用内存对 Redis 的实现来说非常重要. 看一下,Redis 中针对字符串结构针对内存使用效率做的设计优化. 一.SDS的结构 c语言没有string类型,本质是ch ...
- django模糊查询排序
class Book(models.Model): """ 列名 """ class Meta: db_table = 'book' nam ...
- 10分钟理解React生命周期
前言 学习React,生命周期很重要,我们了解完生命周期的各个组件,对写高性能组件会有很大的帮助. 一.简介 React /riˈækt/ 组件的生命周期指的是组件从创建到销毁过程中所经历的一系列方法 ...