有网页打上水印的实现方法么,自己写的会破坏组件布局。

aHR0cHM6Ly9naXRlZS5jb20veXVud2lzZG9tcy93YXRlcm1hcmsvcmF3L21hc3Rlci9leGFtcGxlcy9pbWcvZGVtby5wbmc
类似这样的。

你好,可以这样实现:

  1. 创建自定义主题 :: Jmix 文档 ,由于是修改 body 元素的样式,所以需要在 styles.scss 文件中添加:

    .helium_ext {
      @include addons;
      @include helium_ext;
    }
    
    /*添加下列代码*/
    body::after {
      content: '';
      background-image: var(--watermark);
      background-repeat: repeat;
      background-position: 0 0, 118px 70px;
      position: fixed;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
      z-index: 99;
    }
    

    SCSS中使用了变量 --watermark,用于后续在Java中设置不同的水印文本。如果水印文本不变。那么直接将水印图片设置到 background-image,不需要后续步骤了。

如果是动态文本水印,例如,显示登录用户的登录名,那么请继续看下面的代码:

  1. 在用户登录后,Jmix 会打开 MainScreen 界面,因此,我们可以在该界面的 AfterShow 中添加设置水印的代码:

    @Subscribe
    public void onAfterShow(AfterShowEvent event) {
        // 在 AfterShow 中设置水印
        setWaterMark();
    
        screenTools.openDefaultScreen(
                UiControllerUtils.getScreenContext(this).getScreens());
    
        screenTools.handleRedirect();
    }
    
  2. 下面是一些工具方法,关键地方有注释,可以根据你的实际需要更改:

    // 设置 body::after 中的 --watermark 变量
    private void setWaterMark() {
        String username = currentAuthentication.getUser().getUsername();
        // 修改 scss 中定义的 --watermark 变量,设置为图片的base64
        UI.getCurrent().getPage().getJavaScript().execute(
                "var bodyStyle = document.getElementsByTagName('body')[0].style;" +
                "bodyStyle.setProperty('--watermark', \"url(" + 
                getTextWatermark(username) + ")\");"
        );
    }
    
    // 根据文字生成水印图片的 Base64 编码
    private String getTextWatermark(String text) {
        // 这里可以修改水印图片的大小 - 也就是调整疏密度
        int width = 100;
        int height = 100;
    
        // 创建背景透明的 BufferedImage
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics = image.createGraphics();
        graphics.setComposite(java.awt.AlphaComposite.Clear);
        graphics.fillRect(0, 0, width, height);
        graphics.setComposite(java.awt.AlphaComposite.Src);
    
        // 设置文字的字体、大小和颜色
        graphics.setFont(new Font("Serif", Font.PLAIN, 14));
        graphics.setColor(Color.LIGHT_GRAY);
    
        // 逆时针旋转角度,这里转了 π/8 
        AffineTransform transform = new AffineTransform();
        transform.rotate(-Math.PI / 8, width / 2, height / 2);
        graphics.setTransform(transform);
    
        // 图片中写入文字。
        int stringWidth = graphics.getFontMetrics().stringWidth(text);
        int x = (width - stringWidth) / 2;
        int y = height / 2;
        graphics.drawString(text, x, y);
    
        try {
            // 这里你可以测试一下图片输出
            // ImageIO.write(image, "png", new File("output.png"));
            String base64 = toBase64(image);
            return "'data:image/png;base64," + base64 + "'";
        } catch (Exception e) {
            return "";
        }
    }
    
    // BufferedImage 转 base64 字符串
    private static String toBase64(BufferedImage image) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        byte[] bytes = baos.toByteArray();
        return Base64.getEncoder().encodeToString(bytes);
    }
    

效果如下:
image