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

Word处理控件Aspose.Words功能演示:使用 Java 在 MS Word 文档中进行邮件合并

Aspose.Words 是一种高级Word文档处理API,用于执行各种文档管理和操作任务。API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word。此外,Aspose API支持流行文件格式处理,并允许将各类文档导出或转换为固定布局文件格式和最常用的图像/多媒体格式。

Aspose.words 最新下载(qun 761297826)icon-default.png?t=N176https://www.evget.com/product/4116/download

这篇文章介绍了如何使用 Java 在 MS Word 文档中执行邮件合并操作。到本文结束时,您将了解如何创建邮件合并模板并以编程方式执行邮件合并。
邮件合并是动态生成信件、信封、发票、报告和其他类型文档的便捷方式。使用邮件合并,您可以创建一个包含合并字段的模板文件,然后使用数据源中的数据填充这些字段。假设您要将一封信寄给 20 个不同的人,您只需更改每封信件上收件人的姓名和地址。在这种情况下,您可以为信件创建邮件合并模板,然后通过动态填充姓名和地址字段生成 20 封信件。

一、Java 邮件合并 API - 免费下载

Aspose.Words for Java是一个著名的文字处理 API,可让您从头开始创建各种类型的文档。API 提供内置的邮件合并功能,允许您使用模板和数据源动态生成文档。Aspose.Words for Java 可以作为JAR下载或安装在基于 Maven 的应用程序中。。

<repository>
<id>AsposeJavaAPI</id>
<name>Aspose Java API</name>
<url>https://repository.aspose.com/repo/</url>
</repository><dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>20.11</version>
<classifier>jdk17</classifier>
</dependency>

二、邮件合并的数据源

邮件合并中的数据可以从任何数据源获取,例如 JSON、XML、电子表格或数据库。

三、在 MS Word 中创建邮件合并模板

邮件合并中使用的模板可以是一个简单的 Word 文档(即DOCX),它不需要是模板格式。模板文档包含在执行邮件合并时用数据填充的合并字段。以下是如何使用 MS Word 准备邮件合并模板的步骤。

  • 在 MS Word 中创建一个新文档。
  • 将光标置于要添加合并字段的位置。
  • 插入菜单中选择字段选项。
  • 字段名称列表中,选择MergeField
  • 在字段名称中输入合并字段的名称,然后按确定
  • 将文档另存为 DOCX。

以下是示例模板文档的屏幕截图。

四、使用 Java 创建邮件合并模板

您还可以通过编程方式生成邮件合并模板。以下是它的步骤。

  • 创建DocumentBuilder类的实例。
  • 使用DocumentBuilder提供的方法插入合并字段,例如insertTextInput、insertField、InsertParagraph等。
  • 使用DocumentBuilder.getDocument().save(String fileName)方法保存文档。

以下代码示例显示了如何使用 Java 创建邮件合并模板。

// Create document builder
DocumentBuilder builder = new DocumentBuilder();// Insert a text input field the unique name of this field is "Hello", the other parameters define
// what type of FormField it is, the format of the text, the field result and the maximum text length (0 = no limit)
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Hello", 0);
builder.insertField("MERGEFIELD CustomerFirstName \\* MERGEFORMAT");builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0);
builder.insertField("MERGEFIELD CustomerLastName \\* MERGEFORMAT");builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " , ", 0);// Insert a paragraph break into the document
builder.insertParagraph();// Insert mail body
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Thanks for purchasing our ", 0);
builder.insertField("MERGEFIELD ProductName \\* MERGEFORMAT");builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", please download your Invoice at ",
0);
builder.insertField("MERGEFIELD InvoiceURL \\* MERGEFORMAT");builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "",
". If you have any questions please call ", 0);
builder.insertField("MERGEFIELD Supportphone \\* MERGEFORMAT");builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", or email us at ", 0);
builder.insertField("MERGEFIELD SupportEmail \\* MERGEFORMAT");builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ".", 0);builder.insertParagraph();// Insert mail ending
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Best regards,", 0);
builder.insertBreak(BreakType.LINE_BREAK);
builder.insertField("MERGEFIELD EmployeeFullname \\* MERGEFORMAT");builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0);
builder.insertField("MERGEFIELD EmployeeDepartment \\* MERGEFORMAT");// Save document
builder.getDocument().save("document.docx");

五、使用 Java 在 Word 文档中执行邮件合并

模板准备就绪后,您可以使用数据填充合并字段。以下是在 Word 模板上执行邮件合并的步骤。

  • 使用Document类创建一个新模板(或加载现有模板)。
  • 创建DocumentBuilder类的实例并将Document对象传递给其构造函数。
  • 使用Document.getMailMerge().execute()方法执行邮件合并并将数据源作为参数传递。
  • 使用DocumentBuilder.getDocument().save(String)方法保存生成的 Word 文档。

以下代码示例显示如何使用 Java 在 Word 文档中执行邮件合并。

// Include the code for our template
Document doc = new Document();// Pass the document to document builder
DocumentBuilder builder = new DocumentBuilder(doc);// Create Merge Fields
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");// Save the template
builder.getDocument().save("MailMerge.TestTemplate.docx");// Fill the fields in the document with user data
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
new Object[] { "John Doe", "Hawaiian", "2" });// Save the document
builder.getDocument().save("MailMerge.Simple.docx");

模板

输出

六、使用 XML 数据源执行邮件合并

在前面的示例中,我们使用 Java 对象执行邮件合并。但是,在大多数情况下,数据源用于填充合并字段。为了演示,让我们看看如何在邮件合并中使用 XML 数据源。以下是它的步骤。

  • 使用DataSet类加载 XML 数据源。
  • 使用文档类加载邮件合并模板。
  • 使用执行函数使用数据源中所需的数据表填充合并字段。
  • 使用Document.save(String)方法保存生成的 Word 文档。

以下是此示例中使用的 XML 数据源。

<?xml version="1.0" encoding="utf-8"?>
<customers>
<customer Name="John Ben Jan" ID="1" Domain="History" City="Boston"/>
<customer Name="Lisa Lane" ID="2" Domain="Chemistry" City="LA"/>
<customer Name="Dagomir Zits" ID="3" Domain="Heraldry" City="Milwaukee"/>
<customer Name="Sara Careira Santy" ID="4" Domain="IT" City="Miami"/>
</customers>以下代码示例显示如何使用提供的 XML 数据源中的客户数据表填充邮件合并模板。// Create the Dataset and read the XML
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");// Open a template document
Document doc = new Document("TestFile XML.docx");// Execute mail merge to fill the template with data from XML using DataTable.
// Note that this class also works with a single repeatable region (and any nested regions).
// To merge multiple regions at the same time from a single XML data source, use the XmlMailMergeDataSet class.
// e.g doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));// Save the output document
doc.save("generated-document.docx");

模板

输出

七、邮件与 Java 中的区域合并

在某些情况下,您可能需要重复文档中的特定区域。例如,您想要在单独的表中显示每个客户所下的订单。在这种情况下,您可以利用邮件合并区域。为了创建区域,您可以指定区域的起点和终点。因此,在邮件合并执行期间,将为每个数据实例重复该区域。

以下屏幕截图显示了一个模板,其中区域由一个表组成。它以«TableStart:Customers»开始,以«TableEnd:Customers»结束。

以下代码示例展示了如何创建包含区域的模板并使用数据填充它。

// Create document
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);// The start point of mail merge with regions the dataset.
builder.insertField(" MERGEFIELD TableStart:Customers");
// Data from rows of the "CustomerName" column of the "Customers" table will go
// in this MERGEFIELD.
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");// Create column headers
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();// We have a second data table called "Orders", which has a many-to-one
// relationship with "Customers"
// picking up rows with the same CustomerID value.
builder.insertCell();
builder.insertField(" MERGEFIELD TableStart:Orders");
builder.insertField(" MERGEFIELD ItemName");
builder.insertCell();
builder.insertField(" MERGEFIELD Quantity");
builder.insertField(" MERGEFIELD TableEnd:Orders");
builder.endTable();// The end point of mail merge with regions.
builder.insertField(" MERGEFIELD TableEnd:Customers");// Pass our dataset to perform mail merge with regions.
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);// Save the result
doc.save("MailMerge.ExecuteWithRegions.docx");

输出 

八、使用 Java 创建嵌套邮件合并区域

邮件合并中的另一个流行场景是当您有嵌套区域时。例如,当您必须列出订单和每个订单中的项目时,您可以使用嵌套区域。下图使嵌套区域的图片更加清晰。

在上图中,我们有Orders表和Items表,其中Items中的每条记录都链接到Orders中的一条记录。因此,这两个表之间存在一对多关系。在这种情况下,Aspose.Words 执行邮件合并处理定义在数据集中的关系。例如,如果我们有一个 XML 数据源,那么 Aspose.Words 将使用模式信息或 XML 的结构来找出关系。因此,您不必自己手动处理它,Document.getMailMerge().executeWithRegions(DataSet)方法将为您工作(如前例)。

九、在合并字段上应用自定义格式

为了让您更好地控制邮件合并,Aspose.Words for Java 允许您在邮件合并执行期间自定义合并字段。setFieldMergingCallback (IFieldMergingCallback)方法接受一个实现fieldMerging(FieldMergingArgs)和imageFieldMerging(ImageFieldMergingArgs)方法的类,用于自定义控制邮件合并过程。fieldMerging (FieldMergingArgs)事件在邮件合并执行期间遇到合并字段时发生。

以下是有关如何自定义邮件合并操作并将格式应用于单元格的完整代码示例。

public class ApplyCustomFormattingDuringMailMerge {private static final String dataDir = Utils.getSharedDataDir(ApplyCustomFormattingDuringMailMerge.class) + "MailMerge/";public static void main(String[] args) throws Exception {
Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");// Add a handler for the MergeField event.
doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());// Execute mail merge with regions.
DataTable dataTable = getSuppliersDataTable();
doc.getMailMerge().executeWithRegions(dataTable);doc.save(dataDir + "MailMerge.AlternatingRows Out.doc");
}/**
* Returns true if the value is odd; false if the value is even.
*/
public static boolean isOdd(int value) throws Exception {
return (value % 2 != 0);
}/**
* Create DataTable and fill it with data. In real life this DataTable
* should be filled from a database.
*/
private static DataTable getSuppliersDataTable() throws Exception {
java.sql.ResultSet resultSet = createCachedRowSet(new String[]{"CompanyName", "ContactName"});for (int i = 0; i < 10; i++)
addRow(resultSet, new String[]{"Company " + Integer.toString(i), "Contact " + Integer.toString(i)});return new DataTable(resultSet, "Suppliers");
}/**
* A helper method that creates an empty Java disconnected ResultSet with
* the specified columns.
*/
private static ResultSet createCachedRowSet(String[] columnNames) throws Exception {
RowSetMetaDataImpl metaData = new RowSetMetaDataImpl();
metaData.setColumnCount(columnNames.length);
for (int i = 0; i < columnNames.length; i++) {
metaData.setColumnName(i + 1, columnNames[i]);
metaData.setColumnType(i + 1, java.sql.Types.VARCHAR);
}CachedRowSet rowSet = RowSetProvider.newFactory().createCachedRowSet();
;
rowSet.setMetaData(metaData);return rowSet;
}/**
* A helper method that adds a new row with the specified values to a
* disconnected ResultSet.
*/
private static void addRow(ResultSet resultSet, String[] values) throws Exception {
resultSet.moveToInsertRow();for (int i = 0; i < values.length; i++)
resultSet.updateString(i + 1, values[i]);resultSet.insertRow();// This "dance" is needed to add rows to the end of the result set properly.
// If I do something else then rows are either added at the front or the result
// set throws an exception about a deleted row during mail merge.
resultSet.moveToCurrentRow();
resultSet.last();
}
}class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
/**
* Called for every merge field encountered in the document. We can either
* return some data to the mail merge engine or do something else with the
* document. In this case we modify cell formatting.
*/
public void fieldMerging(FieldMergingArgs e) throws Exception {
if (mBuilder == null)
mBuilder = new DocumentBuilder(e.getDocument());// This way we catch the beginning of a new row.
if (e.getFieldName().equals("CompanyName")) {
// Select the color depending on whether the row number is even or odd.
Color rowColor;
if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx))
rowColor = new Color(213, 227, 235);
else
rowColor = new Color(242, 242, 242);// There is no way to set cell properties for the whole row at the moment,
// so we have to iterate over all cells in the row.
for (int colIdx = 0; colIdx < 4; colIdx++) {
mBuilder.moveToCell(0, mRowIdx, colIdx, 0);
mBuilder.getCellFormat().getShading().setBackgroundPatternColor(rowColor);
}mRowIdx++;
}
}public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception {
// Do nothing.
}private DocumentBuilder mBuilder;
private int mRowIdx;
}

以上便是使用 Java 在 MS Word 文档中进行邮件合并 详细步骤 ,要是您还有其他关于产品方面的问题,欢迎咨询我们,或者加入我们官方技术交流群。

相关文章:

Word处理控件Aspose.Words功能演示:使用 Java 在 MS Word 文档中进行邮件合并

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c;Aspose API支持流行文件格式处理…...

产品未出 百度朋友圈“开演”

ChatGPT这股AI龙卷风刮到国内时&#xff0c;人们齐刷刷望向百度&#xff0c;这家在国内对AI投入最高的公司最终出手了&#xff0c;大模型新项目文心一言&#xff08;ERNIE Bot&#xff09;将在3月正式亮相&#xff0c;对标微软投资的ChatGPT。 文心一言产品未出&#xff0c;百…...

emacs 中的键盘宏

emacs 中的键盘宏 宏定义是emacs比较强大的功能&#xff0c;自定义宏然后绑定快捷键之后就更加爽了。 vim 当然也有宏功能,而且用法简单,例如录制宏到a寄存器:qa...q, 执行宏a: a 世界就是由循环和递归构成的. 宏定义就是一个执行体,为了以后的循环做准备的 开启宏记录 C-x ( 或…...

TCP/IP网络编程——关于 I/O 流分离的其他内容

完整版文章请参考&#xff1a; TCP/IP网络编程完整版文章 文章目录第 16 章 关于 I/O 流分离的其他内容16.1 分离 I/O 流16.1.1 2次 I/O 流分离16.1.2 分离「流」的好处16.1.3 「流」分离带来的 EOF 问题16.2 文件描述符的的复制和半关闭16.2.1 终止「流」时无法半关闭原因16.2…...

【BCT认证_组播DNS】 DNS SRV RR

每天遇见几个罕为人知的Bug&#xff0c;醉了 定义 关键字“必须”、“不能”、“应该”、“不应该”和“可以”本文档中使用的术语应按照 [BCP 14] 中的规定进行解释。本文档中使用的其他术语在 DNS 中定义规范&#xff0c;RFC 1034。 适用性声明 一般情况下&#xff0c;预计…...

【验证码的识别】—— 点触式验证码的识别

一、前言 大家好&#xff0c;不知不觉的我来csdn已经又一周年了&#xff0c;在这一年里&#xff0c;我收获了很多东西&#xff0c;我是2022年2月22日入驻CSDN的&#xff0c;一开始只是为了方便浏览文章的&#xff0c;后来&#xff0c;我也有事没事发发文章&#xff0c;创作了1…...

深入浅出C++ ——priority_queue类深度剖析

文章目录一、priority_queue类简介二、priority_queue类常用接口三、priority_queue类的使用四、STL中priority_queue类的模拟实现一、priority_queue类简介 优先队列是一种容器适配器&#xff0c;根据严格的弱排序标准&#xff0c;它的第一个元素总是它所包含的元素中最大的。…...

117.Android 简单的拖拽列表+防止越界拖动(BaseRecyclerViewAdapterHelper)

//1.第一步 导入依赖库和权限&#xff1a; //依赖库&#xff1a; //RecyclerView implementation com.android.support:recyclerview-v7:28.0.0//RecyclerAdapter implementation com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28 //用到的权限&#xff1a; <!…...

什么是Struts2?有哪些优势

Java中Strutsl是最早的基于MVC模式的轻量级Web框架&#xff0c;它能够合理地划分代码结构&#xff0c;并包含验证框架、国际化框架等多种实用工具框架。但是随着技术的进步&#xff0c;Struts1的局限性也越来越多地暴露出来。为了符合更加灵活、高效的开发需求&#xff0c;Stru…...

Ubuntu22.04 安装Mongodb6.X

Ubuntu22.04 安装Mongodb6.X 1、Mongodb简介 1.1 什么是MongoDB? Mongodb是一个跨平台的面向文档的NoSQL数据库。它使用带有可选模式的类似JSON的BSON来存储数据。应用程序可以以JSON格式检索信息。 1.2 MongoDB的优点 可以快速开发web型应用&#xff0c;因为灵活&#xff0c;…...

启动内核,能启动内核但是无法进入内核,始终卡在某一地方,比如 No soundcards found.

项目场景&#xff1a; 配置好uboot后&#xff0c;启动内核&#xff0c;能启动内核但是无法进入内核&#xff0c;始终卡在某一地方&#xff0c;比如下图 ALSA device list:No soundcards found.问题描述 原因分析&#xff1a; 这是无法进入根文件系统而出现的错误&#xff0c…...

SQL零基础入门学习(六)

SQL零基础入门学习&#xff08;六&#xff09; SQL零基础入门学习&#xff08;五&#xff09; SQL 通配符 通配符可用于替代字符串中的任何其他字符。 SQL 通配符用于搜索表中的数据。 在 SQL 中&#xff0c;可使用以下通配符&#xff1a; 演示数据库 在本教程中&#xff…...

股票、指数、快照、逐笔... 不同行情数据源的实时关联分析应用

在进行数据分析时经常需要对多个不同的数据源进行关联操作&#xff0c;因此在各类数据库的 SQL 语言中均包含了丰富的 join 语句&#xff0c;以支持批计算中的多种关联操作。 DolphinDB 不仅通过 join 语法支持了对于全量历史数据的关联处理&#xff0c;而且在要求低延时的实时…...

华为OD机试真题Python实现【 不含 101 的数】真题+解题思路+代码(20222023)

不含 101 的数 题目 小明在学习二进制时,发现了一类不含 101 的数, 也就是将数字用二进制表示,不能出现 101 。 现在给定一个正整数区间 [l,r],请问这个区间内包含了多少个不含 101 的数? 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Python)真题目录汇…...

centos7 搭建ELK(elasticsearch、logstash、kibana)

1、下载安装包 使用华为镜像站下载速度很快&#xff0c;华为镜像站&#xff1a;https://mirrors.huaweicloud.com/home&#xff0c;下载时需要保证版本一致 2、安装elasticsearch 解压到当前目录 [rootlocalhost elk]# tar zxvf elasticsearch-7.4.2-linux-x86_64.tar.gz 安…...

如何写新闻稿?写好新闻稿的技巧与步骤

新闻稿是传递新闻事件和信息的重要手段&#xff0c;是传媒工作中不可或缺的一部分。写好一篇新闻稿可以让受众了解更多信息&#xff0c;进一步提高他们的关注度。以下是一些写好新闻稿的技巧和步骤&#xff0c;帮助你有效地传达新闻。1、确定新闻的核心信息在开始写新闻稿之前&…...

抖音不想只做“开心果”

出品 | 何玺 排版 | 叶媛 2023一开年&#xff0c;抖音就新动作不断。先是宣布启动线上超市&#xff0c;继而又传出将在3月份试水外卖业务&#xff0c;展现出多面出击的姿态。 01 抖音杀入线上超市、外卖赛道 抖音正式杀入“线上超市”赛道。据多家媒体报道&#xff0c;抖音…...

MATLAB | 如何用MATLAB绘制这样有气泡感的网络图

今天给大家带来一款用来绘制有气泡感的网络图的工具函数&#xff0c;绘制效果如下&#xff1a; 花里胡哨的&#xff0c;气泡大小代表流入流出数据量综合&#xff0c;不同颜色的气泡代表属于不同类&#xff0c;两个气泡之间有连线代表有数据流动&#xff0c;连线透明度代表流动数…...

Linux 远程登录

Linux 一般作为服务器使用&#xff0c;而服务器一般放在机房&#xff0c;你不可能在机房操作你的 Linux 服务器。 这时我们就需要远程登录到Linux服务器来管理维护系统。 Linux 系统中是通过 ssh 服务实现的远程登录功能&#xff0c;默认 ssh 服务端口号为 22。 Window 系统…...

SAP中BOM基础数量及组件数量单位比例关系的注意事项

下图是BOM展开功能CS11在正式系统和测试系统的截图。从截图中的对比不难看出&#xff0c;最下级的原材料A20981-110在组件的数量为1&#xff0c;实际按BOM中的设定比例折算&#xff0c;应该是1个成品&#xff0c;对应需要0.125件原材料。但这里显示的并不是0.125PC&#xff0c;…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...