Browse Source

feat(bszx): 合成图片时支持中文显示

- 在 BszxBmServiceImpl 和 BszxPayServiceImpl 中添加中文支持
- 新增 createChineseFont 方法创建支持中文的字体
- 在图片合成时使用中文字体添加文本元素- 添加 JacksonTest 类进行序列化测试
pan
科技小王子 3 weeks ago
parent
commit
7a485bbc7f
  1. 51
      src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java
  2. 62
      src/main/java/com/gxwebsoft/bszx/service/impl/BszxPayServiceImpl.java
  3. 60
      src/test/java/com/gxwebsoft/JacksonTest.java

51
src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java

@ -9,6 +9,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.freewayso.image.combiner.ImageCombiner;
import com.freewayso.image.combiner.enums.OutputFormat;
import java.awt.Font;
import com.gxwebsoft.bszx.entity.BszxClass;
import com.gxwebsoft.bszx.mapper.BszxBmMapper;
import com.gxwebsoft.bszx.param.BszxClassParam;
@ -32,6 +34,7 @@ import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.File;
import java.time.LocalDateTime;
import java.util.List;
@ -142,6 +145,10 @@ public class BszxBmServiceImpl extends ServiceImpl<BszxBmMapper, BszxBm> impleme
@NotNull
private static ImageCombiner getImageCombiner(BszxBm item, CmsArticle article) throws Exception {
ImageCombiner combiner = new ImageCombiner(article.getAddress(), OutputFormat.JPG);
// 创建支持中文的字体
Font chineseFont = createChineseFont(30);
//加文本元素:姓名
// if (item.getType().equals(0)) {
// combiner.addTextElement(item.getName().concat(" 校友"), 40, 220, 540);
@ -153,11 +160,11 @@ public class BszxBmServiceImpl extends ServiceImpl<BszxBmMapper, BszxBm> impleme
//加图片元素:盖章
// combiner.addImageElement("https://oss.wsdns.cn/20250304/6936b109b09b4919a3498ac5027e728b.png", 600, 1420);
// 使用支持中文的字体添加文本
if (item.getType().equals(0)) {
combiner.addTextElement(item.getName().concat(" 校友"), 30, 160, 1008);
combiner.addTextElement(item.getName().concat(" 校友"), chineseFont, 160, 1008);
} else {
combiner.addTextElement(item.getName(), 30, 160, 1008);
combiner.addTextElement(item.getName(), chineseFont, 160, 1008);
}
// combiner.addTextElement(DateUtil.format(DateUtil.date(), "yyyy年MM月"), 28,650, 1566);
@ -168,6 +175,44 @@ public class BszxBmServiceImpl extends ServiceImpl<BszxBmMapper, BszxBm> impleme
return combiner;
}
/**
* 创建支持中文的字体
* @param fontSize 字体大小
* @return Font对象
*/
private static Font createChineseFont(int fontSize) {
try {
// 尝试使用系统中文字体
String[] chineseFonts = {
"Microsoft YaHei", // 微软雅黑 (Windows)
"SimHei", // 黑体 (Windows)
"SimSun", // 宋体 (Windows)
"PingFang SC", // 苹方 (macOS)
"Hiragino Sans GB", // 冬青黑体 (macOS)
"WenQuanYi Micro Hei", // 文泉驿微米黑 (Linux)
"Noto Sans CJK SC", // 思源黑体 (Linux)
"DejaVu Sans" // 备用字体
};
for (String fontName : chineseFonts) {
Font font = new Font(fontName, Font.PLAIN, fontSize);
// 检查字体是否能正确显示中文
if (font.canDisplay('中')) {
System.out.println("使用字体: " + fontName);
return font;
}
}
// 如果没有找到合适的字体,使用默认字体
System.out.println("警告:未找到支持中文的字体,使用默认字体");
return new Font(Font.SANS_SERIF, Font.PLAIN, fontSize);
} catch (Exception e) {
System.err.println("创建中文字体失败: " + e.getMessage());
return new Font(Font.SANS_SERIF, Font.PLAIN, fontSize);
}
}
@Override
public BszxBm getByUserId(Integer userId) {
return getOne(new LambdaQueryWrapper<BszxBm>().eq(BszxBm::getUserId, userId).last("limit 1"));

62
src/main/java/com/gxwebsoft/bszx/service/impl/BszxPayServiceImpl.java

@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.awt.Font;
import java.io.File;
import java.math.BigDecimal;
import java.util.List;
@ -99,20 +100,25 @@ public class BszxPayServiceImpl extends ServiceImpl<BszxPayMapper, BszxPay> impl
ImageCombiner combiner = new ImageCombiner("https://oss.wsdns.cn/20250908/97f0891f3e4048f5b20ffb07ff370a3a.png?x-oss-process=image/resize,w_750/quality,Q_90", OutputFormat.JPG);
//加图片元素:盖章
// combiner.addImageElement("https://oss.wsdns.cn/20250304/6936b109b09b4919a3498ac5027e728b.png", 550, 926);
// 创建支持中文的字体
Font nameFont26 = createChineseFont(26);
Font nameFont22 = createChineseFont(22);
Font moneyFont = createChineseFont(26);
//加文本元素:姓名
String str;
if (bm.getType().equals(0)) {
str = bm.getName();
combiner.addTextElement(str, 26, 200, 468);
combiner.addTextElement(str, nameFont26, 200, 468);
} else {
str = bm.getName();
combiner.addTextElement(str, 22, 200, 468);
combiner.addTextElement(str, nameFont22, 200, 468);
}
// combiner.addTextElement(bm.getName(), 32,900, 450);
//加文本元素:捐款证书内容
// combiner.addTextElement(" 承您慷慨解囊,襄助百色市百色中学", 32,200, 650);
// combiner.addTextElement("百廿校庆“" + item.getTitle() + "”项目,捐赠人民币", 32,200, 700);
combiner.addTextElement(totalMoney + "", 26, 420, 584);
combiner.addTextElement(totalMoney + "", moneyFont, 420, 584);
// combiner.addTextElement(" 您对学校的支持,为我们共同教育理", 32,200, 800);
// combiner.addTextElement("想的实现增添了一份动力。", 32,200, 850);
// combiner.addTextElement(" 承蒙惠赠,隆情铭感,特颁此证,以资谢旌!", 32, 200, 900);
@ -146,22 +152,28 @@ public class BszxPayServiceImpl extends ServiceImpl<BszxPayMapper, BszxPay> impl
if (ObjectUtil.isNotEmpty(payCert)) {
//合成器(指定背景图和输出格式,整个图片的宽高和相关计算依赖于背景图,所以背景图的大小是个基准)
ImageCombiner combiner = new ImageCombiner("https://oss.wsdns.cn/20250420/811a380e8e124097aa0940a7c68a1f72.jpeg", OutputFormat.JPG);
// 创建支持中文的字体
Font nameFont32 = createChineseFont(32);
Font nameFont22 = createChineseFont(22);
Font moneyFont32 = createChineseFont(32);
//加图片元素:盖章
// combiner.addImageElement("https://oss.wsdns.cn/20250304/6936b109b09b4919a3498ac5027e728b.png", 550, 926);
//加文本元素:姓名
String str;
if (bm.getType().equals(0)) {
str = bm.getName().concat(" 校友");
combiner.addTextElement(str, 32, 930, 450);
combiner.addTextElement(str, nameFont32, 930, 450);
} else {
str = bm.getName();
combiner.addTextElement(str, 22, 880, 450);
combiner.addTextElement(str, nameFont22, 880, 450);
}
// combiner.addTextElement(bm.getName(), 32,900, 450);
//加文本元素:捐款证书内容
// combiner.addTextElement(" 承您慷慨解囊,襄助百色市百色中学", 32,200, 650);
// combiner.addTextElement("百廿校庆“" + item.getTitle() + "”项目,捐赠人民币", 32,200, 700);
combiner.addTextElement(totalMoney + "", 32, 1330, 600);
combiner.addTextElement(totalMoney + "", moneyFont32, 1330, 600);
// combiner.addTextElement(" 您对学校的支持,为我们共同教育理", 32,200, 800);
// combiner.addTextElement("想的实现增添了一份动力。", 32,200, 850);
// combiner.addTextElement(" 承蒙惠赠,隆情铭感,特颁此证,以资谢旌!", 32, 200, 900);
@ -216,4 +228,42 @@ public class BszxPayServiceImpl extends ServiceImpl<BszxPayMapper, BszxPay> impl
return BigDecimal.ZERO;
}
}
/**
* 创建支持中文的字体
* @param fontSize 字体大小
* @return Font对象
*/
private static Font createChineseFont(int fontSize) {
try {
// 尝试使用系统中文字体
String[] chineseFonts = {
"Microsoft YaHei", // 微软雅黑 (Windows)
"SimHei", // 黑体 (Windows)
"SimSun", // 宋体 (Windows)
"PingFang SC", // 苹方 (macOS)
"Hiragino Sans GB", // 冬青黑体 (macOS)
"WenQuanYi Micro Hei", // 文泉驿微米黑 (Linux)
"Noto Sans CJK SC", // 思源黑体 (Linux)
"DejaVu Sans" // 备用字体
};
for (String fontName : chineseFonts) {
Font font = new Font(fontName, Font.PLAIN, fontSize);
// 检查字体是否能正确显示中文
if (font.canDisplay('中')) {
System.out.println("使用字体: " + fontName);
return font;
}
}
// 如果没有找到合适的字体,使用默认字体
System.out.println("警告:未找到支持中文的字体,使用默认字体");
return new Font(Font.SANS_SERIF, Font.PLAIN, fontSize);
} catch (Exception e) {
System.err.println("创建中文字体失败: " + e.getMessage());
return new Font(Font.SANS_SERIF, Font.PLAIN, fontSize);
}
}
}

60
src/test/java/com/gxwebsoft/JacksonTest.java

@ -0,0 +1,60 @@
package com.gxwebsoft;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.gxwebsoft.cms.entity.CmsWebsite;
import lombok.Data;
import org.junit.jupiter.api.Test;
import java.time.LocalDateTime;
/**
* Jackson序列化测试
*/
public class JacksonTest {
@Test
public void testLocalDateTimeSerialization() throws Exception {
// 创建ObjectMapper并注册JavaTimeModule
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
// 创建测试对象
TestObject testObj = new TestObject();
testObj.setName("测试");
testObj.setExpirationTime(LocalDateTime.now());
// 序列化
String json = mapper.writeValueAsString(testObj);
System.out.println("序列化结果: " + json);
// 反序列化
TestObject result = mapper.readValue(json, TestObject.class);
System.out.println("反序列化结果: " + result);
}
@Test
public void testCmsWebsiteSerialization() throws Exception {
// 创建ObjectMapper并注册JavaTimeModule
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
// 创建CmsWebsite对象
CmsWebsite website = new CmsWebsite();
website.setWebsiteName("测试网站");
website.setExpirationTime(LocalDateTime.now());
// 序列化
String json = mapper.writeValueAsString(website);
System.out.println("CmsWebsite序列化结果: " + json);
}
@Data
public static class TestObject {
private String name;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expirationTime;
}
}
Loading…
Cancel
Save