HTML转PDF模板
一、准备pom依赖
<dependency><groupId>com.itextpdf</groupId><artifactId>html2pdf</artifactId><version>1.0.2</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.28</version></dependency>
二、准备sparePartsProcurePoCatalogTemplate.html
相对路径:templates\attrchs\sparePartsProcurePoCatalogTemplate.html
<!DOCTYPE html>
<html>
<meta charset='utf-8'>
<style type='text/css'>body {margin: 0;}.pdfdom {/* width: 900px; */background: #fff;box-sizing: border-box;}.clearfix {clear: both;height: 0;overflow: hidden;align: center}.pdfdom .a4-container {background: #fff;border: 1px solid #ddd;box-sizing: border-box;position: relative;}.pdfdom .a4-container .delivery-title {border-bottom: 2px solid #ddd;box-sizing: border-box;}.pdfdom .a4-container .delivery-title img {width: 100px;box-sizing: border-box;padding-left: 10px;}.pdfdom .a4-container .delivery-title .title {margin: 0;height: 88px;line-height: 88px;margin-left: 30px;}.pdfdom .a4-container .delivery-title .delivery-company-name {float: left;font-weight: bold;line-height: 10px;margin: 15px 0px 0px 25px;}.pdfdom .a4-container .delivery-title .allocate-code {width: 200px;line-height: 15px;font-size: 12px;float: left;margin: 28px 0px 0px 8px;}.pdfdom .a4-container .main-content {border-bottom: 1px solid #ddd;}.pdfdom .a4-container .main-content table tr th,.pdfdom .a4-container .main-content table tr td {border-right: 1px solid #ddd;border-bottom: 1px solid #ddd;padding: 10px;font-size: 13px;font-weight: 700;box-sizing: border-box;}.pdfdom .a4-container .main-content table tr th:last-child,.pdfdom .a4-container .main-content table tr td:last-child {border-right: 0px solid #ddd;}.pdfdom .a4-container .test-container {border-bottom: 1px solid #ddd;display: flex;}.pdfdom .a4-container .test-container .test-container-table {/* width: 100%; */height: 300px;}.pdfdom .a4-container .test-container table tr th,.pdfdom .a4-container .test-container table tr td {border: 1px solid #ddd;padding: 10px 4px;font-size: 12px;/* width: 16%; */box-sizing: border-box;}#body-bottom table tr td {font-size: 14px;}.pdfdom .a4-container .a4-remarks {padding: 14px 10px;line-height: 20px;font-size: 16px;border-bottom: 2px solid #ddd;box-sizing: border-box;}.pdfdom .a4-container .a4-img-container {padding: 14px 10px;font-size: 20px;border-bottom: 2px solid #ddd;}.pdfdom .a4-container .a4-img-container .img-box {float: left;width: 20%;}.pdfdom .a4-container .a4-img-container .img-box .img {display: inline-block;margin: 0 auto;width: 125px;height: 125px;}.pdfdom .a4-container .bottom-content {box-sizing: border-box;}.pdfdom .a4-container .bottom-content table tr th,.pdfdom .a4-container .bottom-content table tr td {border-right: 1px solid #ddd;border-bottom: 1px solid #ddd;width: 50%;padding: 10px;font-size: 16px;vertical-align: middle}.pdfdom .a4-container .bottom-content table tr th:last-child,.pdfdom .a4-container .bottom-content table tr td:last-child {border-right: 0px solid #ddd;}.pdfdom .a4-container .bottom-content .img {height: 90px;}.green {color: #14A16A;}.red {color: #F14855;}.pdfdom .a4-container table {width: 100%;border-collapse: collapse;}.a4-remarks {padding: 14px 10px;line-height: 26px;font-size: 16px;border-bottom: 2px solid #ddd;}.a4-remarks .tc {text-align: center;}.a4-remarks .indent2 {text-indent: 2em;}.a4-remarks .indent3 {text-indent: 3em;}.a4-remarks .lt {margin-top: 15px;color: #333333;}
</style><body>
<div class='pdfdom'><div class='a4-container'><div class='delivery-title'><div style="float:left;"><img style="width: 85px; height:85px;" src="data:image/png;base64,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"></div><div class='delivery-company-name'><h3>采购订单</h3></div><div class='clearfix'></div></div><div class='main-content'><table><tr><td>订单时间:${orderTime!}</td><td>订单编号:${orderCode!}</td></tr><tr><td>需方(甲方):${partyAName!}</td><td>供方(乙方):${partyBName!}</td></tr><tr><td>授权代表:${demandAgent!}</td><td>授权代表:${supplierAgent!}</td></tr><tr><td>地址:${demandAddress!}</td><td>地址:${supplierAddress!}</td></tr><tr><td>联系方式:${demandContactsStyle!}</td><td>联系方式:${supplierContactsStyle!}</td></tr><tr><td colspan="2">经双方友好协议确认,根据下列条款订立本合同:</td></tr><tr><td colspan="2">一、内容:(甲方向乙方订购以下货物):</td></tr></table></div><div class='test-container'><table cellspacing="0" class="test-container-table"><tr><th width="50px">序号</th><th width="100px">零配件SKU名称</th><th width="100px">零配件SKU编码</th><th width="100px">适用车型</th><th width="100px">品牌</th><th width="100px">零配件型号</th><th width="80px">单位</th><th width="80px">数量</th><th width="100px">含税单价(元)</th><th width="100px">含税金额(元)</th><th width="80px">收货人</th><th width="120px">收货人联系方式</th><th width="100px">收货地址</th><th width="100px">预估交期</th></tr><#list a as detail ><tr><td width="50px">${detail.sequence}</td><td width="100px">${detail.skuName}</td><td width="100px">${detail.skuCode}</td><td width="100px">${detail.brandModelName}</td><td width="100px">${detail.brandName}</td><td width="100px">${detail.modelName}</td><td width="80px">${detail.productUnitName}</td><td width="80px">${detail.purchaseQuantity}</td><td width="100px">${detail.unitPriceIncludeTax}</td><td width="100px">${detail.includeTotalAmount}</td><td width="80px">${detail.receivedPerson}</td><td width="120px">${detail.receivedPhone}</td><td width="100px">${detail.receivedAddress}</td><td width="100px">${detail.estimateTime}</td></tr></#list><tr><td colspan="2">货款合计(大写):(含税费及运费)</td><td colspan="6">${totalAmountStr!}</td><td colspan="1">小写合计</td><td colspan="5">${totalAmount!}</td></tr><tr><td colspan="2">备注</td><td colspan="12">${data.remark}</td></tr></table></div><div id="body-bottom" class='test-container'><table cellspacing="0" class="test-container-table"><tr><td colspan="2">二、本订单未约定事宜以关联采购合同编号: ${data.contractCode!}为准。</td></tr><tr><td colspan="2">三、其他约定</td></tr><tr><td colspan="2">1)收货允差天数:正三负零,即提前三天范围内交货是可以接受的,禁止晚交货。</td></tr><tr><td colspan="2">2)供方在收到订单后,请确认品名规格、数量、交期并于1个工作日内签回。</td></tr><tr><td colspan="2">3)本订单未约定的内容以框架合同为准;本订单约定的内容与框架合同不一致的,以本订单为准。</td></tr><tr><td colspan="2">4)本订单中的物料明细不在关联框架合同和补充协议的《供应商产品价格确认表》中的,关于该物料的相关约束使用本订单关联框架合同所有的条款约定 。</td></tr><tr><td colspan="2">5)本合同正本一式贰份,甲乙双方各执壹份,经双方盖章生效;甲方通过指定邮箱向乙方下达的订单与原合同具有同等效力。</td></tr><tr><td align="center">甲方</td><td align="center">乙方</td></tr><tr><td>甲 方(盖章): ${partyAName!}</td><td>乙 方(盖章): ${partyBName!}</td></tr><tr><td>授权代表(签字):</td><td>授权代表(签字):</td></tr></table></div></div>
</div>
</body></html>
三、准备转换代码
/*** 生成 PDF 文件** @param procurePoDTO*/public void generatePdfFile(SparePartsProcurePoDTO procurePoDTO,SSOUser ssoUser) {this.generatePoCatalogPdfToOss(procurePoDTO,ssoUser);}/*** @Description 生成pdf到阿里云* @Param procurePoDTO* @Return void* @Date 2023/10/20 10:24* @Author lwp*/public String generatePoCatalogPdfToOss(SparePartsProcurePoDTO procurePoDTO,SSOUser ssoUser) {SparePartsProcurePo sparePartsProcurePo = procurePoDTO.getSparePartsProcurePo();String orderCode = sparePartsProcurePo.getOrderCode();String htmlStr = this.getHtmlFromPoCatalog(procurePoDTO);String url = "";//渲染pdfFile file = null;String name = AliOSSUtil.generateUUIDName(".pdf");try {File fileDir = new File(System.getProperty("user.dir") + "/pdf/");if (!fileDir.exists()) {fileDir.mkdirs();}file = new File(fileDir.getPath() + "/" + name);file.createNewFile();log.info("采购订单:{} 创建临时文件 {} 是否创建成功:{}", orderCode, file.getPath(), file.exists());} catch (IOException e) {log.error("采购订单:{} PDF生成失败", orderCode, e);}try (FileOutputStream fos = new FileOutputStream(file)) {PdfSupport.convertStringToPdf(htmlStr, fos);log.info("采购订单:{} 上传文件 {} 到阿里云OSS,文件大小 {} byte", orderCode, file.getName(), file.length());url = aliossClient.uploadFile(file, "/procurePo/basic/pdf/"+name);log.info("采购订单:{} PDFURL:{} 上传到阿里云OSS成功", orderCode, url);if (Objects.nonNull(ssoUser)) {uploadExcel(AliOSSHelper.getAccessUrl(url), "易维&四川泰瑞达新能源汽车有限公司-采购订单", ssoUser);}log.info("采购订单:{} PDFURL:{} 数据库更新成功", orderCode, url);} catch (IOException e) {log.error("采购订单:{} PDF生成失败", orderCode, e);} finally {if (file.exists()) {file.delete();}}return url;}/*** @Description 解析生成html格式* @Param procurePoDTO* @Return java.lang.String* @Date 2023/10/20 10:25* @Author lwp*/public String getHtmlFromPoCatalog(SparePartsProcurePoDTO procurePoDTO) {SpareParsProcurePoCatalogTemplateData data = buildData(procurePoDTO);Map<String, Object> params = new HashMap<>();params.put("orderTime",data.getOrderTime());// 订单时间params.put("orderCode", data.getOrderCode());// 订单编号params.put("partyAName", data.getPartyAName());// 需方(甲方)params.put("partyBName", data.getPartyBName());// 供方(乙方)params.put("demandAgent", data.getDemandAgent());// 甲方授权代表params.put("supplierAgent", data.getSupplierAgent());// 乙方授权代表params.put("demandAddress", data.getDemandAddress());// 甲方地址params.put("supplierAddress", data.getSupplierAddress());// 乙方地址params.put("demandContactsStyle", data.getDemandContactsStyle());// 甲方联系方式params.put("supplierContactsStyle", data.getSupplierContactsStyle());// 乙方联系方式params.put("totalAmountStr", data.getTotalAmountStr());// 货款合计(大写):(含税费及运费)params.put("totalPurchaseQuantity", data.getTotalPurchaseQuantity());// 总数量params.put("totalAmount", data.getTotalAmount());// 小写合计params.put("contractCode", data.getContractCode());// 合同编码params.put("paymentMethodName",data.getPaymentMethodName()); //结算方式params.put("invoiceTypeName",data.getInvoiceTypeName()); //发票类型params.put("a", data.getDetails());// 采购订单明细列表return FreemarkerHelper.renderHtml("attrchs/sparePartsProcurePoCatalogTemplate.html", params);}/*** 上传到导出记录* @param url* @param fileName*/public void uploadExcel(String url, String fileName, SSOUser ssoUser){Date date = new Date();ExportRecord exportRecord = new ExportRecord();exportRecord.setFileUrl(url);exportRecord.setFileName(fileName);exportRecord.setModule(10);exportRecord.setModuleName("零配件采购订单");//处理完成exportRecord.setStatus(2);exportRecord.setSource(0);exportRecord.setFileClassification(1);exportRecord.setRequestMethod("GET");exportRecord.setServerName("dst-operate-basic-api");exportRecord.setFileType(FileTypeConstant.PDF);exportRecord.setCreateUserId(ssoUser.getId());exportRecord.setCreateUserName(ssoUser.getRealname());exportRecord.setCreateTime(date);exportRecord.setUpdateUserId(ssoUser.getId());exportRecord.setUpdateUserName(ssoUser.getRealname());exportRecord.setUpdateTime(date);exportRecordService.save(exportRecord);}
四、转换工具 FreemarkerHelper
package com.dst.common.service;import freemarker.cache.URLTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;import java.io.BufferedWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;@Slf4j
public class FreemarkerHelper {private static Configuration config;static {config = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);config.setClassicCompatible(true);config.setLocalizedLookup(false);config.setDateFormat("yyyy-MM-dd");config.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");config.setDefaultEncoding("UTF-8");}public static String renderHtml(String tplName, Map<String,Object> dataModel){String htmlStr = "";try {config.setClassLoaderForTemplateLoading(FreemarkerHelper.class.getClassLoader(),"/templates/");Template tpl = config.getTemplate(tplName);StringWriter stringWriter = new StringWriter();BufferedWriter writer = new BufferedWriter(stringWriter);tpl.process(dataModel,writer);htmlStr = stringWriter.toString();} catch (IOException | TemplateException e) {log.error("【renderHtml】处理html异常:",e);}return htmlStr;}public static String renderHtmlFromUrl(String tplUrl, Map<String,Object> dataModel){String htmlStr = "";try {config.setTemplateLoader(new RemoteTemplateLoader());Template tpl = config.getTemplate(tplUrl);StringWriter stringWriter = new StringWriter();BufferedWriter writer = new BufferedWriter(stringWriter);tpl.process(dataModel,writer);htmlStr = stringWriter.toString();} catch (IOException | TemplateException e) {log.error("【renderHtmlFromUrl】处理html异常:",e);}return htmlStr;}static class RemoteTemplateLoader extends URLTemplateLoader{@Overrideprotected URL getURL(String name) {URL url = null;try {url = new URL(name);} catch (MalformedURLException e) {log.error("【getURL】获取URL异常:",e);}return url;}}public static void main(String[] args) throws Exception {/*URL url = new URL("http://dst2.oss-cn-shenzhen.aliyuncs.com/test_contract_template_af3404a51225458da3ae5a587076f1cf");URLConnection connection = url.openConnection();BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));reader.lines().forEach(line -> System.out.println(line));*/Map<String,Object> dataModel = new HashMap<>();dataModel.put("myDate",new Date());String result = renderHtml("test.html",dataModel);System.out.println(result);// System.out.println(InetAddress.getByName("dst2.oss-cn-shenzhen.aliyuncs.com").getHostAddress());}
}
五、HTML转PDF工具类PdfSupport
package com.dst.common.service;import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.attach.ITagWorkerFactory;
import com.itextpdf.io.font.FontProgram;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.font.FontProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;public abstract class PdfSupport {private static final Logger LOGGER = LoggerFactory.getLogger(PdfSupport.class);public static FontProgram simsun;public static FontProgram awesome;public static ImageData logo;public static FontProvider fontProvider;public static FontProvider createFontProvider() {if (fontProvider == null){fontProvider = new FontProvider();fontProvider.addStandardPdfFonts();fontProvider.addFont(simsun);fontProvider.addFont(awesome);}return fontProvider;}protected static ConverterProperties createConverterProperties(){ConverterProperties prop = new ConverterProperties();prop.setFontProvider(createFontProvider());
// prop.setBaseUri("/static");return prop;}public static void convertToPdf(String htmlStr, OutputStream pdfStream, ConverterProperties converterProperties) throws IOException {HtmlConverter.convertToPdf(htmlStr,pdfStream,converterProperties);}public static void convertStringToPdf(String htmlStr, OutputStream pdfStream, ITagWorkerFactory tagWorkerFactory) throws IOException {ConverterProperties converterProperties = createConverterProperties();converterProperties.setTagWorkerFactory(tagWorkerFactory);HtmlConverter.convertToPdf(htmlStr,pdfStream,converterProperties);}public static void convertStringToPdf(String htmlStr, OutputStream pdfStream) throws IOException {HtmlConverter.convertToPdf(htmlStr,pdfStream,createConverterProperties());}public static PdfDocument createPdfDocument(OutputStream outputStream) throws Exception {return new PdfDocument(new PdfWriter(outputStream));}public static Document convertToDocument(String html, PdfDocument pdfDoc, ConverterProperties prop) throws IOException {return HtmlConverter.convertToDocument(html,pdfDoc,prop);}public void outFile(String fileName, String htmlStr,HttpServletResponse response) {try {String value = "attachment;filename=" + new String((fileName + System.currentTimeMillis() + ".pdf").getBytes("gb2312"), "ISO8859-1");response.setHeader("Content-Disposition", value);response.setContentType("application/octet-stream;charset=utf-8");response.setHeader("Cache-Control", "no-cache");//设置头response.setDateHeader("Expires", 0);//设置日期头OutputStream out = response.getOutputStream();convertToPdf(htmlStr,out);out.flush();} catch (Exception e) {LOGGER.error("OutputStream error", e);}}protected abstract void convertToPdf(String htmlStr, OutputStream out) throws Exception;}
六、转换实体类
package com.dstcar.entitys.sparepartsprocurepo;import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SpareParsProcurePoCatalogTemplateData implements Serializable {/** 采购订单号 规则:CGDD+日期+流水号,按日期累加 **/private String orderCode;/** 订单日期 **/@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")private String orderTime;/** 甲方名称 **/private String partyAName;/** 乙方名称 **/private String partyBName;/** 需方授权代表 **/private String demandAgent;/** 供方授权代表 **/private String supplierAgent;/** 需方地址 **/private String demandAddress;/** 供方地址 **/private String supplierAddress;/** 需方联系方式 **/private String demandContactsStyle;/** 供方联系方式 **/private String supplierContactsStyle;/** 结算方式:1月结30天|2月结60天|3月结90天|4先款后货(字典:spare_parts_payment_method) **/private String paymentMethodName;/** 发票类型:1增值税发票2普通发票(字典:spare_parts_po_invoice_type) **/private String invoiceTypeName;/** 订单总额(产品明细含税总额合计【含税总额(含税单价unitPriceIncludeTax * 采购数量purchaseQuantity)】) **/private BigDecimal totalAmount;/*** 订单总额大写文字*/private String totalAmountStr;/*** 总的采购数量*/private BigDecimal totalPurchaseQuantity;/** 备注 **/private String remark;/** 关联合同号 **/private String contractCode;/** po订单明细 */private List<SpareParsProcurePoCatalogSkuTemplateData> details;}package com.dstcar.entitys.sparepartsprocurepo;import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.math.BigDecimal;@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SpareParsProcurePoCatalogSkuTemplateData implements Serializable {/*** 序号*/private Integer sequence;/** 零配件sku名称 **/private String skuName;/** 零部件SKU编码 **/private String skuCode;/*** 适用车型名称* 备注:适用车型下拉框选择‘通用’时该字段为空* 适用车型下拉框选择‘部分车型适用’时该字段翻译(适用车型里面的品牌+型号拼接而成)*/private String brandModelName;/*** 零配件品牌名称*/private String brandName;/*** 零配件型号名称*/private String modelName;/** 计量单位 */private String productUnitName;/** 采购数量 **/private BigDecimal purchaseQuantity;/** 含税单价 **/private BigDecimal unitPriceIncludeTax;/** 含税总额(含税单价*采购数量) **/private BigDecimal includeTotalAmount;/** 收货人 **/private String receivedPerson;/** 收货人联系电话 **/private String receivedPhone;/** 收货人地址 **/private String receivedAddress;/** 预估交期 **/@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")private String estimateTime;}
七、最终转换效果

相关文章:
HTML转PDF模板
一、准备pom依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>html2pdf</artifactId><version>1.0.2</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId&g…...
Clickhouse学习笔记(14)—— Clickhouse监控
ClickHouse 运行时会将一些个自身的运行状态记录到众多系统表中,如下所示: 为了直观方便地监控ck的运行情况,使用Prometheus Grafana 的组合来进行监控 Prometheus 负责收集各类系统的运行指标;Grafana 负责可视化 Prometheus&a…...
Vue3 + Three.js + gltf-pipeline大型园区场景渲染与3D业务
在非使用unity作为3D渲染方案的前提下,对与目前web开发者比较友好的除了canvas场景需要的2D babylon.js,fabric.js, Three.js是目前针对于jsWeb用户最直接且比较友好的3D引擎方案了。 准备工作: 1.明确需要用的场景方案都有那些,模…...
基于FPGA的PS端的Si5340的控制
1、功能 Si5340/41-D可以输出任意频率,当然有范围,100Hz1GHz。外部输入为24M或者4854M的XTAL,VCO在13500~14256Mhz之间,控制接口采用IIC或者SPI。 芯片架构图 2、IIC控制方式 3、直接上控制代码 使用米联客ZU3EG,将…...
安装 Lua 的 HTTP 库
首先,你需要安装 Lua 的 HTTP 库。可以使用 LuaRocks 来安装。以下是安装命令: luarocks install http然后,你可以使用以下代码来爬取网页内容: local http require http-- 设置代理信息 http.set_proxy(jshk.com.cn)-- 网页UR…...
Redis解决缓存问题
目录 一、引言二、缓存三、Redis缓存四、缓存一致性1.缓存更新策略2.主动更新 五、缓存穿透六、缓存雪崩七、缓存击穿1.基于互斥锁解决具体业务2.基于逻辑过期解决具体业务 一、引言 在一些大型的网站中会有十分庞大的用户访问流量,而过多的用户访问对我们的MySQL数…...
七个合法学习黑客技术的网站,让你从萌新成为大佬
大家好我是若风,一个8年网络安全攻防经验的白帽黑客。 合法的学习网站,以下这些网站,虽说不上全方位的满足你的需求,但是大部分也都能。能带你了解到黑客有关的技术,视频,电子书,实践࿰…...
【数据结构】面试OJ题——带环链表(数学推论)
目录 1.环形链表Ⅰ 编辑 思路 : 思路拓展 问题一: 问题二: 总结: 问题三: 证明总结第三点 总结: 2. 环形链表Ⅱ 思路一 思路二 3.相交链表 思路: 1.环形链表Ⅰ 141. 环形链…...
PostgreSQL中pg_ctl工具的使用
pg_ctl工具有以下功能: (1)初始化postgresql数据库实例 (2)启动、终止或重启postgresql数据库服务 (3)查看postgresql数据库服务的状态 (4)让数据库实例重新读取配置…...
深入理解Kafka3.6.0的核心概念,搭建与使用
Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景&a…...
【python】编程题小代码
空心题(平行四边形) layer int(input("请输入你要打印的行数:")) for i in range(1,layer // 2 2): space_num layer - i for j in range(0,space_num): print(" ",end "") star_num 2 * i - 1 for j in range(0,sta…...
抖音小程序开发全攻略:如何规划项目和选择合适的开发团队
在数字化时代,抖音小程序成为企业推广和服务的重要渠道。本文将为您提供抖音小程序开发的全面攻略,重点介绍如何规划项目和选择合适的开发团队,并附有一些关键的技术代码示例。 1. 项目规划 在开始抖音小程序开发之前,详细的项…...
PSP - 蛋白质复合物结构预测 模版配对(Template Pair) 逻辑的特征分析
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/134328447 在 蛋白质复合物结构预测 的过程中,模版 (Template) 起到重要作用,提供预测结果的关于三维结构的先验信息&…...
喜报不断!箱讯平台获评2023年上海市促进现代航运服务业创新示范项目
近期,可谓捷报频传!在箱讯科技子公司苏州箱讯获评苏州市软件和信息服务业 “头雁”培育企业没过多久,就又迎来好消息! 日前,上海市交通委发布“2023年上海市促进现代航运服务业创新项目”评选结果,箱讯An…...
SOME/IP学习笔记3
目录 1.SOMEIP Transformer 1.1 SOME/IP on-wire format 1.2 协议指定 2. SOMEIP TP 2.1 SOME/IP TP Header 3.小结 1.SOMEIP Transformer 根据autosar CP 相关规范,SOME/IP Transformer主要用于将SOME/IP格式的数据序列化,相当于一个转换器。总体…...
【ATTCK】ATTCK开源项目Caldera学习笔记
CALDERA是一个由python语言编写的红蓝对抗工具(攻击模拟工具)。它是MITRE公司发起的一个研究项目,该工具的攻击流程是建立在ATT&CK攻击行为模型和知识库之上的,能够较真实地APT攻击行为模式。 通过CALDERA工具,安全…...
黑窗口连接远程服务
ssh root192.168.x.x 回车输入密码 查看docker docker ps 停止正在运行的服务 docker stop xxxxx 删除服务 docker rm xxxxx 查看镜像 docker images 删除镜像 docker rmi xxxxx 删除镜像 启动并运行整个服务 docker compose up -d jar包名称 idea 使用tcp方式连接docker 配置d…...
好消息!2023年汉字小达人市级比赛在线模拟题大更新:4个组卷+11个专项,助力孩子更便捷、有效、有趣地备赛
自从《中文自修》杂志社昨天发通知,官宣了2023年第十届汉字小达人市级比赛的日期和安排后,各路学霸们闻风而动,在自己本就繁忙的日程中又加了一项:备赛汉字小达人市级比赛,11月30日,16点-18点。 根据这几年…...
SAP 70策略测试简介
在前面的文章中我们已经测试了10、11、20、40、50、52、60、62策略的测试,接下来我们需要对70策略进行测试,很多的项目中也都会用到70策略。 70策略是一种比较常见的、基于按库存且主要用于半成品或者原材料的计划策略。 我们还是按照之前的惯例,先看下70策略的后台配置 我…...
uniapp+vue3+ts+vite+echarts开发图表类小程序,将echarts导入项目使用的详细步骤,耗时一天终于弄好了
想在uniapp和vue3环境中使用echarts是一件相当前卫的事情,官方适配的还不是很好,echarts的使用插件写的是有些不太清晰的,这里我花费了一天的时间,终于将这个使用步骤搞清楚了,并且建了一个仓库,大家可以直…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
