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文档.本人文采欠缺,写作能力 ...
随机推荐
- StyleGAN 生成 AI 虚拟人脸,再也不怕侵犯肖像权
目录 什么是 StyleGAN 如何使用 StyleGAN 下载项目 修改项目 MSVC 运行项目 运行结果 什么是 StyleGAN GAN 是机器学习中的生成性对抗网络,目标是合成与真实图像无法区 ...
- linux使用汇总
linux使用汇总 Linux的目录结构 没有逻辑磁盘分区(C盘.D盘...) 是一棵树形结构,根目录是/ 根目录下边有几个文件夹,需要我们了解: /etc:配置文件所在的文件夹.比如:安装JDK,配 ...
- InnoDB 索引深入剖析
InnoDB页 将数据划分为若干个页(page),以页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为 16KB.也就是在一般情况下,一次最少从磁盘中读取16KB的内容到内存中,一次最少 ...
- git 从本地仓库提交至远程仓库 报错:error: failed to push some refs to "xxx"
**原因**:远程库里面有个文件,但是本地没有这个文件,比如: README.md,完全提交上去会覆盖之前的文件,所以git会提示报错警告! **解决方案**:如果只有 README.md文件,可以使 ...
- Teamcenter_NX集成开发:通过NXOpen查询零组件是否存在
之前用过NXOpen PDM的命名空间下的类,现在记录一下通过PDM命名空间下的类查询Teamcenter零组件的信息,也可以用来判断该零组件是否存在. 1-该工程为DLL工程,直接在NX界面调用,所 ...
- 为什么wait()需要在同步代码块内使用
我们还是通过源代码和代码注释来学习这个问题 我们先来看看wait方法的注释,这里截取最根源的native方法给的注释 Causes the current thread to wait until e ...
- flutter ui---->一些类QQ的实现
整理一下比较有意思的类QQ的UI实现.Nothing that has meaning is easy. Easy doesn't enter into grown-up life. darken t ...
- 前端ffmpeg实现视频剪切
利用ffmpeg实现纯前端视频剪切 注意:在新版本Chrome浏览器中由于安全性问题,只能在https或localhost当中才能正常使用 1. 下载ffmpeg npm install @ffmpe ...
- C++的一些随笔(第一篇)
C++中 ->的作用 ->用于指针 ->用于指向结构体的指针 ->用于指向结构体的指针,表示结构体内的元素 #include<stdio.h> struct ro ...
- Django之数据库操作入门
目录 pycharm连接mysql数据库 pycharm与数据库图形化交互方式 pycharm后台连接数据库 django连接数据库报错 ORM简介 ORM建表 ORM入门之增删改查 ORM写数据 O ...