背景是由于 Linux 下无中文字体,导致写中文乱码,又不想引入环境依赖。
SpringBoot 项目,ttf 或 ttc 文件放置于 resource/font/cn.ttf
。
POM 添加打包配置,避免 ttf 文件打包时被处理导致文件 FontFormatException
损坏。
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
加载字体 Font
对象相关代码
package com.seliote.utils.font;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ResourceUtils;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Objects;
/**
* 字体相关工具
*
* @author seliote
* @since 2022-03-28
*/
@Slf4j
public class FontUtils {
/**
* 加载中文字体
*
* @param style 字体样式
* @param size 字体大小
* @return 中文字体
*/
public static Font loadCNFont(int style, float size) throws Exception {
final String fontFile = "/font/cn.ttf";
final String fontFamily = "宋体";
GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontFamilies = graphicsEnvironment.getAvailableFontFamilyNames();
log.info("Total available font {}", fontFamilies.length);
for (String eachFamily : fontFamilies) {
if (fontFamily.equals(eachFamily)) {
log.info("Font in env, return");
return new Font(fontFamily, style, (int) Math.ceil(size));
}
}
Font font;
if (isInJar()) {
log.debug("Running in JAR mode, try load resource TTC");
font = Font.createFont(Font.TRUETYPE_FONT,
Objects.requireNonNull(FontUtils.class.getClassLoader().getResourceAsStream(fontFile)));
} else {
log.debug("Running in local mode, try load classpath TTC");
font = Font.createFont(Font.TRUETYPE_FONT,
new File(ResourceUtils.getURL("classpath:").getPath(), fontFile));
}
font = font.deriveFont(style, size);
log.info("Register font family {}", fontFamily);
graphicsEnvironment.registerFont(font);
return font;
}
/**
* 判断当前是否为 JAR 方式启动
*
* @return 当为 true 时为 JAR 方式启动,否则为非 JAR
*/
private static boolean isInJar() {
try {
Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources("");
if (resources.hasMoreElements()) {
log.debug("Application is in JAR!");
return StringUtils.equalsIgnoreCase(resources.nextElement().getProtocol(), "jar");
}
} catch (IOException e) {
log.error("Failed load resource, ", e);
throw new RuntimeException(e);
}
log.debug("Application is not in JAR!");
return false;
}
}
使用时
FontUtils.loadCNFont(Font.PLAIN, fontSize)