aspose-words / Aspose.Words-for-Java

Aspose.Words for Java examples, plugins and showcases
https://products.aspose.com/words/java
MIT License
401 stars 206 forks source link

word添加水印后页眉变高 #94

Closed chengshuanghub closed 1 year ago

chengshuanghub commented 1 year ago

如果页眉只有一行的时候,添加完水印后页眉会变成2行,整个文档的内容都会往下移。 版本:15.8.0

代码:

public static void setWordWaterMarkss(String inputFileName, String outputFileName, String watermarkText, String watermarkImage) {
        loadLicense();
        try {
            Document document = new Document(inputFileName);
            insertWatermarkText(document, watermarkText, nodes -> null);
            //insertWatermarkImage(document, watermarkImage, nodes -> null);
            //文件输出路径
            document.save(outputFileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void insertWatermarkText(Document doc, String watermarkText,
                                            Function<Shape, Object> watermaskPositionConfigFunc) {
        loadLicense();
        Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT);
        watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
        watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
        watermark.setWrapType(WrapType.NONE);
        watermark.setVerticalAlignment(VerticalAlignment.CENTER);
        watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);
        watermark.getTextPath().setText(watermarkText);
        // 这里设置为宋体可以保证在转换为PDF时中文不是乱码.
        watermark.getTextPath().setFontFamily("宋体");
        try {
            // 水印大小
            watermark.setWidth(500);
            watermark.setHeight(70);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 左下到右上
        watermark.setRotation(-50);
        //字体RGB颜色
        watermark.getFill().setColor(Color.LIGHT_GRAY);
        watermark.setStrokeColor(Color.LIGHT_GRAY);
        watermaskPositionConfigFunc.apply(watermark);
        Paragraph watermarkPara = new Paragraph(doc);
        watermarkPara.appendChild(watermark);
        for (Section sect : doc.getSections()) {
            insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
        }

    }

    private static void insertWatermarkImage(Document doc, String watermarkImage,
                                             Function<Shape, Object> watermaskPositionConfigFunc) {
        loadLicense();
        Shape watermark = new Shape(doc, ShapeType.IMAGE);
        watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
        watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
        watermark.setWrapType(WrapType.NONE);
        watermark.setVerticalAlignment(VerticalAlignment.CENTER);
        watermark.setHorizontalAlignment(HorizontalAlignment.RIGHT);
        try {
            watermark.getImageData().setImage(watermarkImage);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            // 水印大小
            watermark.setWidth(100);
            watermark.setHeight(100);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //字体RGB颜色
        watermaskPositionConfigFunc.apply(watermark);
        Paragraph watermarkPara = new Paragraph(doc);
        watermarkPara.appendChild(watermark);
        for (Section sect : doc.getSections()) {
            insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
        }
    }

    private static void insertWatermarkIntoHeader(Paragraph watermarkPara, Section sect,
                                                  int headerType) {
        HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType);
        if (header == null) {
            header = new HeaderFooter(sect.getDocument(), headerType);
            sect.getHeadersFooters().add(header);
        }
        try {
            header.appendChild(watermarkPara.deepClone(true));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static void getKey() {
        try {
            KeyGenerator _generator = KeyGenerator.getInstance(AES_KEY);
            SecureRandom secureRandom = SecureRandom.getInstance(SHA1PRNG_KEY);
            secureRandom.setSeed(AES_KEY.getBytes());
            _generator.init(secureRandom);
            key = _generator.generateKey();
            _generator = null;
        } catch (Exception e) {
            throw new RuntimeException("Error initializing SqlMap class. Cause: " + e);
        }
    }

    /**
     * 从Classpath(jar文件中)中读取License
     */
    private static void loadLicense() {
        //返回读取指定资源的输入流
        License license = new License();
        InputStream is = null;
        try {
            ClassPathResource resource = new ClassPathResource("aspose_lic.xml");
            is = resource.getInputStream();
            if(is==null){
                throw new RuntimeException("License文件不存在或者错误");
            }
            license.setLicense(is);
        } catch (Exception ex) {
            ex.printStackTrace();
        }finally{
            if(is!=null){
                try{ is.close(); }catch(IOException ex){ };
                is = null;
            }
        }
    }

    public static void main(String[] args) {
        setWordWaterMarkss("C:\\Users\\DELL\\Desktop\\页眉测试.docx",
            "C:\\Users\\DELL\\Desktop\\水印测试\\test4.doc",
            "111111111",
            "");
    }

添加水印前: image

t添加水印后: image

AlexNosk commented 1 year ago

@chengshuanghub 您能否在此处附上您的输入和输出文件以供我们参考。 我们将检查问题并为您提供更多信息。 顺便说一句,最新版本的 Aspose.Words 提供了一种在文档中添加水印的内置方法: https://docs.aspose.com/words/java/working-with-watermark/

chengshuanghub commented 1 year ago

@chengshuanghub 您能否在此处附上您的输入和输出文件以供我们参考。 我们将检查问题并为您提供更多信息。 顺便说一句,最新版本的 Aspose.Words 提供了一种在文档中添加水印的内置方法: https://docs.aspose.com/words/java/working-with-watermark/

麻烦您帮忙看看。

输入文件: 页眉测试.docx 输出文件: test4.docx

AlexNosk commented 1 year ago

@chengshuanghub 出现此问题的原因是您插入带有段落的水印。 请看下面的截图。 为避免该问题,您应该在现有段落中插入水印形状。 image 或者您可以简单地使用内置方法插入水印:

Document doc = new Document("C:\\Temp\\in.docx");
doc.getWatermark().setText("11111111111111111111111");
doc.save("C:\\Temp\\out.docx");

out.docx

chengshuanghub commented 1 year ago

@chengshuanghub 出现此问题的原因是您插入带有段落的水印。 请看下面的截图。 为避免该问题,您应该在现有段落中插入水印形状。 image 或者您可以简单地使用内置方法插入水印:

Document doc = new Document("C:\\Temp\\in.docx");
doc.getWatermark().setText("11111111111111111111111");
doc.save("C:\\Temp\\out.docx");

out.docx

您好,这个带有段落的水印不是我代码里加的,是加完水印后页眉就变成了2行,我添加的水印是不带段落的。内置方法插入好像设置不了位置,我们需要插入多个水印。

AlexNosk commented 1 year ago

@chengshuanghub 在您的代码中,您为水印形状创建一个段落并将其附加到每个部分的每个标题中。 请参阅以下代码片段:

Paragraph watermarkPara = new Paragraph(doc);
watermarkPara.appendChild(watermark);
for (Section sect : doc.getSections()) {
    insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
}

正如我提到的,如果标题已经包含一个段落,您应该在这个现有段落中插入一个水印形状,而不是创建一个单独的段落。

chengshuanghub commented 1 year ago

@chengshuanghub 在您的代码中,您为水印形状创建一个段落并将其附加到每个部分的每个标题中。 请参阅以下代码片段:

Paragraph watermarkPara = new Paragraph(doc);
watermarkPara.appendChild(watermark);
for (Section sect : doc.getSections()) {
    insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
}

正如我提到的,如果标题已经包含一个段落,您应该在这个现有段落中插入一个水印形状,而不是创建一个单独的段落。

请问您有获取现有段落并插入水印的例子吗?

官网也是我这样写的 image

AlexNosk commented 1 year ago

@chengshuanghub 您可以使用如下代码:

HeaderFooter hf = sect.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY);
if(hf!=null)
{
    hf.getFirstParagraph().appendChild(watermarkShape.deepClone(true));
}
chengshuanghub commented 1 year ago

@chengshuanghub 您可以使用如下代码:

HeaderFooter hf = sect.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY);
if(hf!=null)
{
    hf.getFirstParagraph().appendChild(watermarkShape.deepClone(true));
}

@AlexNosk 您好,我替换成上面的代码后,程序报错。您能帮忙看看吗? image

报错信息: java.lang.IllegalArgumentException: Cannot insert a node of this type at this location. at com.aspose.words.CompositeNode.zzWwL(Unknown Source) at com.aspose.words.CompositeNode.insertAfter(Unknown Source) at com.aspose.words.CompositeNode.appendChild(Unknown Source) at FileUtils.insertWatermarkIntoHeader(FileUtils.java:220) at FileUtils.insertWatermarkText(FileUtils.java:180) at FileUtils.setWordWaterMarkss(FileUtils.java:143) at FileUtils.main(FileUtils.java:301)

AlexNosk commented 1 year ago

@chengshuanghub 在您的代码中,您试图将一个段落插入另一个段落。 您应该插入水印形状,而不是水印段落。你应该插入这个节点

Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT);
chengshuanghub commented 1 year ago
watermarkShape

@AlexNosk 插入水印形状后好了,谢谢您的帮助