部署到服务器上时图片文件、excel文件、ppt文件添加水印时中文全部显示“口口口口口”问题

问题描述

在将项目部署到服务器并运行在 Docker 容器中时,下载文件添加水印时,所有水印的中文字符均显示为“口口口口口”,而不是预期的中文文本。

问题产生原因

  • Word文档使用ShapeObject来添加水印,这通常是因为Word的API支持将文本作为形状(Shape)来处理,并且word文件格式支持直接嵌入字体和样式。因此,可以直接在 Word 文档中添加文本水印,而不需要将其转换为图片。
  • Excel和PowerPoint文档使用Font对象来创建字体,并将文本转化为图像来创建水印,以更加方便的控制水印的位置和样式。但Font对象的创建,依赖于服务器上已有的字体,因此如果服务器中没有对应的字体,java会使用默认字体,但是如果默认字体不支持中文,就可能会导致中文显示不正确。

解决方案1 :将字体放进项目中在代码中动态加载

获取字体文件包

需要那种字体可以直接在网上下载。

或者直接在自己的windows电脑上进行导出来,导出来的字体也是TTF后缀的字体文件。

进入电脑C盘的C:\Windows\Fonts 目录,里面是电脑的所有字体,直接将里面的文件复制出来使用即可。

将复制出来的字体文件放入resources目录下的fonts文件夹下

src
├── main
│   ├── java
│   └── resources
│       └── fonts
│           └── simsun.ttc
字体工具类

编写创建Font对象的字体工具类

import java.awt.*;
import java.io.InputStream;
import java.util.Objects;

/** * 字体工具类. */
public class FontUtils {

    private FontUtils() {
    }

    /**     * 从资源文件加载本地字体.     *     * @paramfontPath  字体路径, 相对 resources 目录的相对路径, 如 fonts/simsun.ttc     * @paramfontStyle 字体风格, 可选值: Font.PLAIN, Font.BOLD, Font.ITALIC     * @paramfontSize  字体大小     * @return字体     */public static Font loadLocalFont(String fontPath, int fontStyle, float fontSize) {
        Font font;
        try (InputStream fontStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(fontPath)) {
            if (Objects.isNull(fontStream)) {
                throw new FontException("Font resource is null.");
            }

            font = Font.createFont(Font.TRUETYPE_FONT, fontStream);
            font = font.deriveFont(fontStyle, fontSize);
        } catch (Exception e) {
            throw new FontException(e.getMessage(), e.getCause());
        }
        return font;
    }

    /**     * 字体异常.     */static class FontException extends RuntimeException {

        public FontException(String message) {
            super(message);
        }

        public FontException(String message, Throwable cause) {
            super(message, cause);
        }
    }
}
使用
// 水印文字字体private static Font font= FontUtils.loadLocalFont("fonts/simsun.ttc", Font.BOLD, 20);

然后使用font对象创建的字体就可以正常表示中文了。

解决方案二:将字体导入到服务器中

进入服务器此目录下 /usr/share/fonts,将下载好的TTF字体包上传到服务器的 /usr/share/fonts目录下

然后执行命令

mkfontscale

mkfontdir

fc-cache

查看是否安装成功,执行命令:此命令是仅查找中文字体,如果想查询服务器所有字体,可以输入命令:fc-list

fc-list :lang=zh

执行命令能够查询到,就证明安装好了

如果想删除字体,直接将 /usr/share/fonts这个目录下对应的字体TTF包删除,然后执行命令:

sudo fc-cache -fv

理论上到这里导入字体应该就可以了。

但是由于我的项目是使用docker部署的,因此刚开始执行到这一步并没有解决我的问题。

后来想了想,应该还需要将字体文件拷贝到docker容器中的/usr/share/fonts/目录下。

其他可能执行的操作:

启动项目时指定编码utf8

ENTRYPOINT ["java", "-Dfile.encoding=utf-8","-jar","filesystem-netdisk.jar"]

点赞

当前页面评论已关闭。

隐藏
变装