当前位置: 首页 > news >正文

freemarker生成pdf,同时pdf插入页脚,以及数据量大时批量处理

最近公司有个需求,就是想根据一个模板生成一个pdf文档,当即我就想到了freemarker这个远古老东西,毕竟freemarker在模板渲染方面还是非常有优势的。

准备依赖:

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>html2pdf</artifactId><version>3.0.5</version></dependency><!--pdf 支持中文(默认不支持)--><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency>

我这里不想选freemarker版本,直接用spring集成的省事。
配置一下freemarker的配置

import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;import java.io.IOException;@Component
@org.springframework.context.annotation.Configuration
public class FreemarkerConfig {// 我这里为了省事,不想创建那么多的Configuration,而且创建Configuration太多不好@Bean(name = "cfg")public Configuration freemarkerConfigurer() throws IOException {// 选择版本,不同版本对不同的模板语法或者模板转换也会有差异,如果你css 样式比较新,建议选高版本准没错Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);// 选择你存放模板的位置final ClassPathResource classPathResource = new ClassPathResource("templates");cfg.setDirectoryForTemplateLoading(classPathResource.getFile());cfg.setDefaultEncoding("UTF-8");// 模板异常处理cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);return cfg;}
}

然后我们准备下我们的ftl模板【freemarker的模板文件】----pdf.ftl
freemarker框架类似于beetlthymeleafjspVelocity等模板引擎
JSP就不用说了吧,基本上开发Java的基本上都会了解开发过

<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<style>.logo {width: 320px;height: 80px;}.user-info {padding: 10px 10px;background: RGB(221, 235, 247);}.label {width: 150px;padding: 0 20px 0 0;text-align: left;}.time {width: 100px;margin-right: 10px;text-align: center;}.label, .time {display: inline-block;}.range-time {margin: 20px 0;}.table-data {width: 100%;}table{border-collapse: collapse;}.header > th {text-align: left;height: 50px;}.divider-line {margin: 20px 0;height: 3px;background: #000;}.desc {padding: 15px 10px;}.date {width: 100px;}.fee {width: 50px;}.name {width: 140px;}.name, .fee, .date {padding: 0 10px;}.download-date {text-align: right;}.bottom-footer-tip {width: 100%;margin-top: 300px;font-size: 12px;transform: scale(.9);}
</style>
<body><div class="download-date">Download on 2022/2/2</div>
<div class="range-time"><span class="time">${startTime}</span><span>to</span><span class="time">${endTime}</span>
</div><table class="table-data"><tr class="header"><th>Date</th><th>Name</th><th>desc</th><th>fee</th></tr><tr class="divider-line"><th></th><th></th><th></th><th></th></tr><#list list as item><tr><td class="date">${item.date}</td><td class="name">${item.name}</td><td class="desc"><div>${item.desc}</div></td><td class="fee">${item.fee}</td></tr></#list><tr class="divider-line"><th></th><th></th><th></th><th></th></tr>
</table>
</body>
</html>

这里ftl的语法,我就不多做解释了,我这里附上freemarker的官方文档,感兴趣的自己去学习一下。

然后准备下我们的代码处理逻辑

首先是PDF实体数据

import lombok.Data;import java.util.List;@Data
public class PDFData {private String logo;private String name;private String address;private String startTime;private String endTime;private List<TableData> list;
}

然后是关联(table)数据


import lombok.Data;@Data
public class TableData {private String date;private String desc;private String name;private String fee;
}

然后我们处理我们处理逻辑的代码

import com.alibaba.fastjson.JSONObject;
import com.example.web.pojo.TableData;
import com.example.web.pojo.PDFData;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.font.FontProvider;
import com.itextpdf.layout.property.TextAlignment;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;@Component
public class FreemarkerExecution {// 准备下字体文件private static String FONT = "./src/main/resources/templates/AlibabaPuHuiTi-3-65-Medium.ttf";// 后续转pdf时的配置private static ConverterProperties converterProperties = new ConverterProperties();private static String base64LogoData = null;{FontProvider dfp = new DefaultFontProvider();//添加字体库dfp.addFont(FONT);//设置解析属性converterProperties.setFontProvider(dfp);converterProperties.setCharset("utf-8");try {// 有一个logo处理,因为一般服务器渲染的话一般建议将部分图片处理成base64然后放进来,或者大家看看其他的方式base64LogoData = imgToBase64(new FileInputStream("./src/main/resources/templates/logo.png"));} catch (FileNotFoundException e) {e.printStackTrace();}}@Resource(name = "cfg")private Configuration configuration;// 普通处理逻辑public void converterHTML() {// 这个会将处理后的html语法输出至 命令行窗口,可以手动创建一个html文件,然后把结果复制进去直接打开查看try (Writer out = new OutputStreamWriter(System.out)) {// 获取数据final PDFData pdfData = getData();Template temp = configuration.getTemplate("pdf.ftl");// 直接写出文件temp.process(pdfData, out);} catch (IOException e) {e.printStackTrace();} finally {}}private void writeToPDF(Template template, Map<String, Object> dataModel) {try {final File file = new File("D:/pdf/test.html");template.process(dataModel, new OutputStreamWriter(new FileOutputStream(file)));final File pdfFile = new File("D:/pdf/test.pdf");HtmlConverter.convertToPdf(file, pdfFile, converterProperties);PdfReader reader = new PdfReader(new File("D:/pdf/test.pdf"));PdfWriter writer = new PdfWriter(new FileOutputStream("D:/pdf/test_1.pdf"));PdfDocument pdfDocument = new PdfDocument(reader, writer);// 页大小final PageSize pageSize = pdfDocument.getDefaultPageSize();// 页数final int numberOfPages = pdfDocument.getNumberOfPages();for (int i = 1; i <= numberOfPages; i++) {PdfPage page = pdfDocument.getPage(i);final PdfDocument pdfDoc = page.getDocument();final Document document = new Document(pdfDoc);final Paragraph paragraph = new Paragraph("Page" + i).setFont(PdfFontFactory.createFont(FONT)).setFontColor(new DeviceRgb(0, 0, 0)).setFixedPosition(i, 0, 10, pageSize.getWidth()).setFontSize(10).setTextAlignment(TextAlignment.CENTER);document.add(paragraph);}pdfDocument.close();reader.close();writer.close();} catch (Exception e) {e.printStackTrace();}}private PDFData getData() throws FileNotFoundException {PDFData data = new PDFData();data.setName("重生之我是蔡徐坤");data.setAddress("蔡徐坤蔡徐坤喜欢唱跳rap篮球");data.setStartTime("01-Feb-22");data.setEndTime("28-Feb-22");data.setLogo("data:image/png;base64," + base64LogoData);final LocalDateTime nowTime = LocalDateTime.now();final List<TableData> arr = new ArrayList<>();for (int i = 0; i < 10; i++) {final TableData tableData = new TableData();tableData .setDesc(i % 2 == 0 ? "交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大" : "交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大");tableData .setName("蔡徐坤" + i);tableData .setFee(1000 + i + "");tableData .setDate(nowTime.plusDays(-i).format(DateTimeFormatter.ofPattern("YYYY/MM/dd")));arr.add(tableData);}data.setList(arr);return data;}private String imgToBase64(InputStream inputStream) {byte[] data = null;try {data = new byte[inputStream.available()];inputStream.read(data);inputStream.close();} catch (IOException e) {e.printStackTrace();}return Base64.getEncoder().encodeToString(data);}
}

这里会又有一个问题出现,就是我们一般处理PDF的时候,数据不可能一次性处理到内存中,因为我们服务器内存等问题,假如我们有100w数据,肯定不能一次性查出来,由此我们就需要批量处理,这里我们可以将模板拆分开,重复的数据放一个模板文件,然后后续进行模板的组装。

首先,我将一个ftl模板文件拆成了三个 👉 header.ftl,content.ftl,footer.ftl,然后再由一个主的核心ftl模板来组装这几个模板。
思路:准备上述模板文件,然后渲染模板后继续解析成ftl模板文件,然后读取选然后的ftl模板文件,然后转成html,最后通过html文件处理成pdf文件。

这里content.ftl是批量的数据,因为不能一次读取大量数据,所以这里content.ftl要单独处理一下。

Main.ftl
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<style>.logo {width: 320px;height: 80px;}.user-info {padding: 10px 10px;background: RGB(221, 235, 247);}.label {width: 150px;padding: 0 20px 0 0;text-align: left;}.time {width: 100px;margin-right: 10px;text-align: center;}.label, .time {display: inline-block;}.range-time {margin: 20px 0;}.table-data {width: 100%;}table {border-collapse: collapse;}.header > th {text-align: left;height: 50px;}.divider-line {margin: 20px 0;height: 3px;background: #000;}.desc {padding: 15px 10px;}.date {width: 100px;}.name {width: 50px;}.fee{width: 140px;}.fee, .name , .date {padding: 0 10px;}.download-date {text-align: right;}.bottom-footer-tip {width: 100%;margin-top: 300px;font-size: 12px;transform: scale(.9);}
</style>
<body>${headerPath}
<table class="table-data"><tr class="header"><th>Date</th><th>Desc</th><th>Name</th><th>Fee</th></tr><tr class="divider-line"><th></th><th></th><th></th><th></th></tr><#list contentPathList as content>${content}</#list><tr class="divider-line"><th></th><th></th><th></th><th></th></tr>
</table>
${footerPath}<#--<#include "header.ftl">-->
<#--<#include "content.ftl">-->
<#--<#include "footer.ftl">--></body>
</html>
header.ftl
<img src="${logo}" class="logo">
<div class="download-date">Download on 2022/2/2</div>
<div class="user-info"><div><div class="label">User:</div><span>${name}</span></div><div><div class="label">Address:</div><span>${address}</span></div>
</div><div class="range-time"><span class="time">${startTime}</span><span>to</span><span class="time">${endTime}</span>
</div>
content.ftl
<#list list as item><tr><td class="date">${item.date}</td><td class="desc"><div>${item.desc}</div></td><td class="fee">${item.fee}</td><td class="name">${item.name}</td></tr></#list>
footer.ftl
<#list list as item><tr><td class="date">${item.date}</td><td class="desc"><div>${item.desc}</div></td><td class="fee">${item.fee}</td><td class="name">${item.name}</td></tr></#list>
核心处理逻辑
    void allTemplatesWriteToPDF() {// 所有子模板final List<String> ftlNameList = new ArrayList<>();try {// 读取对应的模板文件final Template template = getTemplate("content.ftl");final Template headerTemplate = getTemplate("header.ftl");final Template footerTemplate = getTemplate("footer.ftl");final PDFData data = getData();// 先处理头部和尾部headerTemplate.process(data, new FileWriter("D:/pdf/content/header.ftl"));footerTemplate.process(data, new FileWriter("D:/pdf/content/footer.ftl"));// mock 模拟数据库查询10次for (int i = 0; i < 10; i++) {// 组装10条数据,算上10次循环一共100条数据final PDFData pdfData = getData();String fileName = "D:/pdf/content/content" + i + ".ftl";final FileWriter writer = new FileWriter(fileName);// 存储最后框架模板的数据,这里是存储了freemarker include 语法连接所有的需要组装的数据模板名称ftlNameList.add("<#include \"" + fileName.substring(fileName.lastIndexOf("/") + 1, fileName.lastIndexOf(".")) + ".ftl \"/>");// 生成对应的模板文档template.process(pdfData, writer);writer.flush();writer.close();}// 获取所有子模板final Configuration cdf = new Configuration(Configuration.VERSION_2_3_22);cdf.setDirectoryForTemplateLoading(new File("D:/pdf/content"));cdf.setDefaultEncoding("UTF-8");cdf.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);final Template mainTemplate = getTemplate("main.ftl");final HashMap<Object, Object> map = new HashMap<>();map.put("headerPath", "<#include \"" + "header.ftl\"/>");map.put("contentPathList", ftlNameList);map.put("footerPath", "<#include \"" + "footer.ftl\"/>");mainTemplate.process(map, new FileWriter("D:/pdf/content/main.ftl"));final Template cdfTemplate = cdf.getTemplate("main.ftl");cdfTemplate.process(null, new FileWriter("D:/pdf/content/main.html"));final File pdfFile = new File("D:/pdf/test_new.pdf");HtmlConverter.convertToPdf(new File("D:/pdf/content/main.html"), pdfFile, converterProperties);PdfReader reader = new PdfReader(pdfFile);PdfWriter writer = new PdfWriter(new FileOutputStream("D:/pdf/test_new_1.pdf"));PdfDocument pdfDocument = new PdfDocument(reader, writer);// 页大小final PageSize pageSize = pdfDocument.getDefaultPageSize();// 页数final int numberOfPages = pdfDocument.getNumberOfPages();// 这里是处理页脚数据for (int i = 1; i <= numberOfPages; i++) {PdfPage page = pdfDocument.getPage(i);final PdfDocument pdfDoc = page.getDocument();final Document document = new Document(pdfDoc);final Paragraph paragraph = new Paragraph("Page" + i).setFont(PdfFontFactory.createFont(FONT)).setFontColor(new DeviceRgb(0, 0, 0)).setFixedPosition(i, 0, 10, pageSize.getWidth()).setFontSize(10).setTextAlignment(TextAlignment.CENTER);document.add(paragraph);}pdfDocument.close();reader.close();writer.close();} catch (IOException | TemplateException e) {e.printStackTrace();}}private Template getTemplate(String name) throws IOException {return configuration.getTemplate(name);}

在这里插入图片描述

在这里插入图片描述

OK,大概就这样,剩下的大家自己去玩吧, 解散!!!

相关文章:

freemarker生成pdf,同时pdf插入页脚,以及数据量大时批量处理

最近公司有个需求&#xff0c;就是想根据一个模板生成一个pdf文档&#xff0c;当即我就想到了freemarker这个远古老东西&#xff0c;毕竟freemarker在模板渲染方面还是非常有优势的。 准备依赖&#xff1a; <dependency><groupId>org.springframework.boot</gr…...

勇攀新高峰|暴雨信息召开2024年中述职工作会议

7月8日至9日&#xff0c;暴雨信息召开2024年中述职工作会议&#xff0c;总结回顾了上半年的成绩和不足&#xff0c;本次会议采用线上线下的方式举行&#xff0c;公司各部门管理人员、前台市场营销人员参加述职&#xff0c;公司领导班子出席会议。 本次述职采取了现场汇报点评的…...

C++:filter2D函数简要概述

OpenCV中的filter2D函数是一个非常强大的工具&#xff0c;用于对图像进行卷积操作&#xff0c;从而应用各种线性滤波器。这个函数能够处理图像中的每个像素&#xff0c;通过将其与指定的卷积核&#xff08;或称为滤波器&#xff09;进行卷积运算&#xff0c;来修改图像的特性。…...

Postman使用教程【项目实战】

目录 引言软件下载及安装项目开发流程1. 创建项目2. 创建集合(理解为&#xff1a;功能模块)3. 设置环境变量&#xff0c;4. 创建请求5. 测试脚本6. 响应分析7. 共享与协作 结语 引言 Postman 是一款功能强大的 API 开发工具&#xff0c;它可以帮助开发者测试、开发和调试 API。…...

微软Phi-3:小型而强大的AI模型解析与实战指南

微软Phi-3&#xff1a;小型而强大的AI模型解析与实战指南 引言 随着人工智能技术的飞速发展&#xff0c;小型而高效的AI模型逐渐成为研究与应用的新热点。微软研究院推出的Phi-3系列模型&#xff0c;以其卓越的性能和高效的成本效益&#xff0c;在AI领域引起了广泛关注。本文…...

Python 获取 SQL 指纹和 HASH 值

前言 本文介绍一个提取 SQL 指纹的方法&#xff0c;就是将 SQL 语句的条件转换为 &#xff1f;可用于脱敏和 SQL 聚类分析的场景。 1. 工具安装 这里用到的工具&#xff0c;就是 pt 工具集中的 pt-fingerprint 含在 Percona Toolkit 中&#xff0c;安装方法可参考 Percona T…...

基于OpenCv的快速图片颜色交换,轻松实现图片背景更换

图片颜色更换 图片颜色转换 当我们有2张图片,很喜欢第一张图片的颜色,第2张图片的前景照片,很多时候我们需要PS进行图片的颜色转换,这当然需要我们有强大的PS功底,当然小编这里不是介绍PS的,我们使用代码完全可以代替PS 进行图片的颜色转换 图片颜色转换步骤: 步骤…...

在Linux下直接修改磁盘镜像文件的内容

背景 嵌入式Linux系统通常在调试稳定后&#xff0c;会对磁盘&#xff08;SSD、NVME、SD卡、TF卡&#xff09;做个镜像&#xff0c;通常是.img后缀的文件&#xff0c;以后组装新设备时&#xff0c;就将镜像文件烧录到新磁盘即可&#xff0c;非常简单。 这种方法有个不便之处&a…...

ASP.NET Core----基础学习03----开发者异常页面 MVC工作原理及实现

文章目录 1. 开发者异常页面(1)Startup.cs 页面的基础配置(2)自定义显示报错代码的前后XX行 2. MVC 的原理3. MVC 的实现4.默认路由路径5.返回Json字符串 1. 开发者异常页面 (1)Startup.cs 页面的基础配置 namespace ASP.Net_Blank {public class Startup{private readonly IC…...

jvm 07 GC算法,内存池,对象内存分配

01 垃圾判断算法 1.1引用计数算法 最简单的垃圾判断算法。在对象中添加一个属性用于标记对象被引用的次数&#xff0c;每多一个其他对象引用&#xff0c;计数1&#xff0c; 当引用失效时&#xff0c;计数-1&#xff0c;如果计数0&#xff0c;表示没有其他对象引用&#xff0c;…...

ComfyUI入门教程

本文主要介绍了通过源码运行comfyui&#xff0c;默认例子介绍&#xff0c;节点管理器的使用&#xff0c;以及界面汉化。可多参考开源工作流&#xff0c;多加实践&#xff0c;从而掌握comfyui操作。 1.源码运行comfyui 执行命令python main.py如下&#xff1a; 安装numpy 1.x最…...

Flutter TabBar与TabBarView联动及获取当前点击栏目索引

TabBar还有TabBarView都是谷歌flutter官方组件库——Material组件库提供的组件&#xff0c;其中TabBar用于导航切换&#xff0c;TabBarView则是配合其切换显示的对应的视图&#xff0c;官网参考地址&#xff1a;TabBarView class - material library - Dart API。 实现一体联动…...

【区块链+跨境服务】跨境出口电商溯源 | FISCO BCOS应用案例

当前跨境出口电商已成为带动我国外贸发展的中坚力量&#xff0c;尤其疫情特殊时期&#xff0c;成为推动经济增长的一个重要组成 部分。但是跨境出口电商流程长、环节多&#xff0c;且需辗转于不同的服务商以及国家之间&#xff0c;监管与定位也相对困难&#xff0c;容 易出现诸…...

记录一次mysql死锁问题的分析排查

记录一次死锁问题的分析排查 现象 底层往kafka推送设备上线数据应用层拉取设备上线消息,应用层有多个消费者并发执行将设备上线数据同步数据库表pa_terminal_channel日志报&#xff1a;&#xff08;Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: …...

【UE5.1 角色练习】16-枪械射击——瞄准

目录 效果 步骤 一、瞄准时拉近摄像机位置 二、瞄准偏移 三、向指定方向射击 四、连发 效果 步骤 一、瞄准时拉近摄像机位置 打开角色蓝图&#xff0c;在事件图表中添加如下节点&#xff0c;当进入射击状态时设置目标臂长度为300&#xff0c;从而拉近视角。 但是这样切…...

04OLED简介和调试方法

OLED简介和调试方法 调试方式串口调试显示屏调试其他调试方法总结&#xff1a; OLED简介硬件电路OLED驱动函数 keil调试模式进入方法keil调试界面窗口简单功能说明更加强大的功能 调试方式 电脑想看什么变量可以直接打印到屏幕&#xff0c;但是单片机很多时候由于成本和电路结构…...

“LNMP环境搭建实战指南:从零开始配置CentOS 7下的Nginx、MySQL与PHP“

目录 1.前言 2.准备工作 2.1.环境信息 2.2.关闭SELinux和firewalld 3.安装Nginx 3.1.运行以下命令&#xff0c;安装Nginx 3.2.运行以下命令&#xff0c;查看Nginx版本 4.安装MySQL 4.1.更新秘钥 4.2.配置MySQL的YUM仓库 4.3.安装MySQL 4.4.查看MySQL版本 4.5.启动…...

院内导航:如何用科技破解就医找路难题

自2019年开始“院内导航”被纳入医院智慧服务评估体系以来&#xff0c;到2023年改善就医服务升级的部署&#xff0c;每一步都见证了我国医疗卫生体系向智能化、人性化迈进的坚实步伐。 面对庞大复杂的医院环境与日益增长的就诊需求&#xff0c;如何让患者在茫茫人海中迅速找到就…...

C++基础篇(1)

目录 前言 1.第一个C程序 2.命名空间 2.1概念理解 2.2namespace 的价值 2.3 namespace的定义 3.命名空间的使用 4.C的输入输出 结束语 前言 本节我们将正式进入C基础的学习&#xff0c;话不多说&#xff0c;直接上货&#xff01;&#xff01;&#xff01; 1.第一个C程…...

云视频监控中的高效视频转码策略:视频汇聚EasyCVR平台H.265自动转码H.264能力解析

随着科技的快速发展&#xff0c;视频监控技术已经广泛应用于各个领域&#xff0c;如公共安全、商业管理、教育医疗等。与此同时&#xff0c;视频转码技术作为视频处理的关键环节&#xff0c;也在不断提高视频的质量和传输效率。 一、视频监控技术的演进 视频监控技术的发展历…...

Qwen3-ASR-1.7B实战教程:结合Punctuation Restoration模型提升标点准确率

Qwen3-ASR-1.7B实战教程&#xff1a;结合Punctuation Restoration模型提升标点准确率 语音识别技术已经相当成熟&#xff0c;但识别结果往往缺少标点符号&#xff0c;让长文本阅读变得困难。本文将教你如何将Qwen3-ASR-1.7B语音识别模型与标点恢复技术结合&#xff0c;获得既准…...

释放创意:Mi-Create让智能表盘设计触手可及

释放创意&#xff1a;Mi-Create让智能表盘设计触手可及 【免费下载链接】Mi-Create Unofficial watchface creator for Xiaomi wearables ~2021 and above 项目地址: https://gitcode.com/gh_mirrors/mi/Mi-Create 问题发现&#xff1a;智能表盘设计的三重困境 在智能穿…...

Phi-3-mini-4k-instruct-gguf实战教程:开箱即用的轻量中文问答部署指南

Phi-3-mini-4k-instruct-gguf实战教程&#xff1a;开箱即用的轻量中文问答部署指南 1. 认识Phi-3-mini-4k-instruct-gguf Phi-3-mini-4k-instruct-gguf是微软Phi-3系列中的轻量级文本生成模型GGUF版本。这个模型特别适合处理中文问答、文本改写、摘要整理以及简短创作等任务。…...

如何将 iQOO 手机备份到Mac

iQOO是vivo旗下的智能手机品牌&#xff0c;以其强劲的性能、出色的游戏体验和极具竞争力的价格而闻名。它深受那些希望以合理价格购买高性能Android手机的用户欢迎。然而&#xff0c;由于缺乏官方的 macOS 管理工具&#xff0c;许多用户发现将 iQOO 手机备份到Mac并非易事。幸运…...

从大疆NAZA换到匿名P2飞控:一个DIY玩家的真实体验与参数调试避坑指南

从大疆NAZA到匿名P2飞控&#xff1a;一位DIY玩家的深度迁移指南 当我的F450机架在狭小卧室里显得笨拙不堪时&#xff0c;我意识到需要一次彻底的"瘦身计划"。这不是简单的机架更换&#xff0c;而是一次从商业飞控到开源系统的完整迁移——将大疆NAZA积累的经验移植到…...

告别桌面图标混乱:NoFences让你的数字空间井然有序

告别桌面图标混乱&#xff1a;NoFences让你的数字空间井然有序 【免费下载链接】NoFences &#x1f6a7; Open Source Stardock Fences alternative 项目地址: https://gitcode.com/gh_mirrors/no/NoFences 你是否曾打开电脑就被满屏散乱的图标淹没&#xff1f;工作文件…...

告别云端依赖:AnythingLLM本地Whisper实现完全离线语音转文字

告别云端依赖&#xff1a;AnythingLLM本地Whisper实现完全离线语音转文字 【免费下载链接】anything-llm The all-in-one AI productivity accelerator. On device and privacy first with no annoying setup or configuration. 项目地址: https://gitcode.com/GitHub_Trendi…...

别再到处找了!这12个三维点云开源数据集,够你从入门到项目实战

三维点云实战指南&#xff1a;12个精选开源数据集与精准匹配策略 当你第一次打开三维点云处理软件&#xff0c;面对空白的项目界面&#xff0c;最迫切的问题往往是&#xff1a;"我该从哪里获取高质量的训练数据&#xff1f;"这个问题困扰过每一位初学者&#xff0c;…...

Python MCP服务端框架源码剖析(2024最新LTS版内核解密)

第一章&#xff1a;Python MCP服务端框架源码剖析&#xff08;2024最新LTS版内核解密&#xff09;Python MCP&#xff08;Modular Control Protocol&#xff09;服务端框架2024 LTS版标志着其架构从单体调度向轻量级异步模块总线的重大演进。该版本基于 Python 3.11 构建&#…...

Qwen3.5-2B部署实战:端侧轻量化多模态模型一键镜像教程

Qwen3.5-2B部署实战&#xff1a;端侧轻量化多模态模型一键镜像教程 1. 模型简介 Qwen3.5-2B是阿里云推出的轻量化多模态基础模型&#xff0c;属于Qwen3.5系列的小参数版本&#xff08;20亿参数&#xff09;。这个模型专为低功耗、低门槛部署场景设计&#xff0c;特别适合端侧…...