Añadir marca de agua a documentos de Microsoft Office

Añadir marca de agua a documentos de Microsoft Office

Herramienats disponibles

  1. Apache POI: una biblioteca de Java, Apache POI - la API de Java para documentos de Microsoft
  2. Open XML SDK: biblioteca de C#, GitHub - OfficeDev/Open-XML-SDK: Open XML SDK por Microsoft
  3. Free Spire.Office para Java https://www.e-iceblue.cn/Introduce/Free-Spire-Office-JAVA.html

Para este artículo, se utilizará principalmente Apache POI.

EXCEL

Para agregar una marca de agua en Excel, solo puedes insertarla como imagen, existen dos métodos:

Uno es pegar directamente la imagen, pero esto ocultará el contenido del texto y afectará la edición del documento.

import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;

public class MiClase {
    public static void main(String[] args) throws IOException {
        // Leer archivo xlsx
        XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\proyecto\\archivo.xlsx")));
        // Leer imagen
        InputStream is = new FileInputStream("C:\\Users\\DELL\\Desktop\\proyecto\\marca_de_agua.png");
        byte[] bytes = IOUtils.toByteArray(is);
        int pictureIdx = excel.addPicture(bytes, excel.PICTURE_TYPE_PNG);
        is.close();

        for (int i = 0; i < excel.getNumberOfSheets(); i++) {
            XSSFSheet xssfSheet = excel.getSheetAt(i);
            XSSFDrawing drawing = xssfSheet.createDrawingPatriarch();
            for (int xCount = 0; xCount < 10; ++xCount) {
                for (int yCount = 0; yCount < 10; ++yCount) {
                    // Crear posición de la imagen de marca de agua
                    int xIndexInteger = xCount * 5 + xCount * 5;
                    int yIndexInteger = yCount * 5 + yCount * 5;
                    XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, xIndexInteger, yIndexInteger, xIndexInteger + 5, yIndexInteger + 5);
                    XSSFPicture pict = drawing.createPicture(anchor, pictureIdx);
                    pict.resize();
                }
            }
        }
        // Guardar nuevo archivo
        String file = "C:\\Users\\DELL\\Desktop\\marcado2archivo33.xlsx";
        OutputStream fileOut = new FileOutputStream(file);
        excel.write(fileOut);
    }
}

El otro método es establecerlo como fondo, aunque no afecta la edición, no se puede ajustar el estilo del fondo (incluyendo inclinación o disposición).

Solo se pueden realizar operaciones como la inclinación al momento de generar la imagen y luego incorporarla como fondo.

import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;

public class MiClase {

    public static void main(String[] args) throws IOException {
        // Leer archivo xlsx
        XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\proyecto\\archivo.xlsx")));
        // Leer imagen
        InputStream is = new FileInputStream("C:\\Users\\DELL\\Desktop\\proyecto\\marca_de_agua.png");
        byte[] bytes = IOUtils.toByteArray(is);
        int pictureIdx = excel.addPicture(bytes, excel.PICTURE_TYPE_PNG);
        is.close();

        // Agregar relación entre hoja y imagen
        for (int i = 0; i < excel.getNumberOfSheets(); i++) {
            XSSFSheet xssfSheet = excel.getSheetAt(i);
            String rID = xssfSheet.addRelation(null, XSSFRelation.IMAGES, excel.getAllPictures().get(pictureIdx)).getRelationship().getId();
            xssfSheet.getCTWorksheet().addNewPicture().setId(rID);
        }
        // Guardar nuevo archivo
        String file = "C:\\Users\\DELL\\Desktop\\marcado2archivo22.xlsx";
        OutputStream fileOut = new FileOutputStream(file);
        excel.write(fileOut);
    }
}

Generar imagen e incorporarla

Se puede generar la imagen con inclinación y otros estilos, y luego incorporarla como fondo.

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class MiClase {
    public static class MarcaDeAgua {
        public String texto;
        public int ancho = 400;
        public int alto = 400;
        public String color;
        public String fuente;
        public int tamañoFuente = 10;
        public double Xshear;
        public double Yshear;
        MarcaDeAgua(String texto, String color, String fuente, double Xshear, double Yshear) {
            this.texto = texto;
            this.color = color;
            this.fuente = fuente;
            this.Xshear = Xshear;
            this.Yshear = Yshear;
        }
        public BufferedImage crearMarcaDeAgua() {
            BufferedImage imagen = new BufferedImage(ancho, alto, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = imagen.createGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, ancho, alto);
            g.setColor(new Color(Integer.parseInt(color, 16)));
            g.setFont(new Font(fuente, Font.BOLD, tamañoFuente));
            g.shear(Xshear, Yshear);
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.drawString(texto, 20, 100);
            g.dispose();
            return imagen;
        }
    }
    public static void main(String[] args) throws IOException {
        // Leer archivo xlsx
        XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\proyecto\\archivo.xlsx")));
        // Leer imagen
        MarcaDeAgua marcaDeAgua = new MarcaDeAgua("Marca de agua muestra", "00FFFF", "Arial", 0.1, -0.28);
        BufferedImage imagen = marcaDeAgua.crearMarcaDeAgua();
        ByteArrayOutputStream is = new ByteArrayOutputStream();
        ImageIO.write(imagen, "png", new FileOutputStream("C:\\Users\\DELL\\Desktop\\1.png"));
        ImageIO.write(imagen, "png", is);
        int pictureIdx = excel.addPicture(is.toByteArray(), excel.PICTURE_TYPE_PNG);
        is.close();

        // Agregar relación entre hoja y imagen
        for (int i = 0; i < excel.getNumberOfSheets(); i++) {
            XSSFSheet xssfSheet = excel.getSheetAt(i);
            String rID = xssfSheet.addRelation(null, XSSFRelation.IMAGES, excel.getAllPictures().get(pictureIdx)).getRelationship().getId();
            xssfSheet.getCTWorksheet().addNewPicture().setId(rID);
        }
        // Guardar nuevo archivo
        String file = "C:\\Users\\DELL\\Desktop\\marcado2archivo22.xlsx";
        OutputStream fileOut = new FileOutputStream(file);
        excel.write(fileOut);
    }
}

Versiones antiguas de Excel

Las versiones antiguas de Excel parecen permitir únicamente insertar imágenes como marca de agua, no se puede agregar como fondo. Intentando usar Free Spire.Office for Java, parece que tampoco se puede agregar como fondo, además hay algún conflicto con la biblioteca que no se puede resolver temporalmente. Así que actualmente solo se puede generar imágenes transparentes, lo que no afecta la lectura pero sí la edición.

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Picture;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class MiClase {
    public static class MarcaDeAgua {
        public String texto;
        public int ancho = 400;
        public int alto = 400;
        public String color;
        public String fuente;
        public int tamañoFuente = 42;
        public double Xshear;
        public double Yshear;
        MarcaDeAgua(String texto, String color, String fuente, double Xshear, double Yshear) {
            this.texto = texto;
            this.color = color;
            this.fuente = fuente;
            this.Xshear = Xshear;
            this.Yshear = Yshear;
        }
        public BufferedImage crearMarcaDeAgua() {
            BufferedImage imagen = new BufferedImage(ancho, alto, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = imagen.createGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, ancho, alto);
            g.setColor(new Color(Integer.parseInt(color, 16)));
            g.setFont(new Font(fuente, Font.BOLD, tamañoFuente));
            g.shear(Xshear, Yshear);
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.drawString(texto, 20, 100);
            g.dispose();
            return imagen;
        }
    }
    public static void main(String[] args) throws IOException {
        // Leer archivo xlsx
        HSSFWorkbook excel = new HSSFWorkbook(new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\prueba.xls")));
        // Leer imagen
        MarcaDeAgua marcaDeAgua = new MarcaDeAgua("Marca de agua muestra", "000000", "Arial", 0.1, -0.28);
        BufferedImage imagen = marcaDeAgua.crearMarcaDeAgua();
        ByteArrayOutputStream is = new ByteArrayOutputStream();
        ImageIO.write(imagen, "png", new FileOutputStream("C:\\Users\\DELL\\Desktop\\marca_de_agua.png"));
        ImageIO.write(imagen, "png", is);
        int pictureIdx = excel.addPicture(is.toByteArray(), excel.PICTURE_TYPE_PNG);
        is.close();
        CreationHelper helper = excel.getCreationHelper();
        // Agregar relación entre hoja y imagen
        for (int i = 0; i < excel.getNumberOfSheets(); i++) {
            HSSFSheet hssfSheet = excel.getSheetAt(i);
            Drawing drawing = hssfSheet.createDrawingPatriarch();
            ClientAnchor anchor = helper.createClientAnchor();
            anchor.setCol1(3);
            anchor.setRow1(2);
            anchor.setDx1(6);
            Picture pict = drawing.createPicture(anchor, pictureIdx);
            pict.resize();
        }
        // Guardar nuevo archivo
        String file = "C:\\Users\\DELL\\Desktop\\prueba_generada.xls";
        OutputStream fileOut = new FileOutputStream(file);
        excel.write(fileOut);
    }
}

WORD

Insertar imagen

Insertar imagen, se puede definir el tamaño, la posición y el ángulo de rotación. El resultado se muestra en la siguiente imagen.

import com.microsoft.schemas.vml.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class MiClase {
    public static class MarcaDeAgua {
        public String texto;
        public int ancho = 400;
        public int alto = 400;
        public String color;
        public String fuente;
        public int tamañoFuente = 10;
        public double Xshear;
        public double Yshear;
        MarcaDeAgua(String texto, String color, String fuente, double Xshear, double Yshear) {
            this.texto = texto;
            this.color = color;
            this.fuente = fuente;
            this.Xshear = Xshear;
            this.Yshear = Yshear;
        }
        public BufferedImage crearMarcaDeAgua() {
            BufferedImage imagen = new BufferedImage(ancho, alto, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = imagen.createGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, ancho, alto);
            g.setColor(new Color(Integer.parseInt(color, 16)));
            g.setFont(new Font(fuente, Font.BOLD, tamañoFuente));
            g.shear(Xshear, Yshear);
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.drawString(texto, 20, 100);
            g.dispose();
            return imagen;
        }
    }
    public static class Estilo {
        public String posicion = "absoluto";
        public String ancho = "100";
        public String alto = "100";
        public String rotacion = "315";
        public String posicion_horizontal = "centro";
        public String posicion_horizontal_relativa = "margen";
        public String posicion_vertical = "centro";
        public String posicion_vertical_relativa = "margen";

        public Estilo(String ancho, String alto, String rotacion, String posicion_horizontal, String posicion_vertical) {
            this.ancho = ancho;
            this.alto = alto;
            this.rotacion = rotacion;
            this.posicion_horizontal = posicion_horizontal;
            this.posicion_vertical = posicion_vertical;
        }

        public String getValorString() {
            return "posicion:" + this.posicion + ";ancho:" + this.ancho + ";alto:" + this.alto + ";rotacion:" + this.rotacion + ";mso-posicion-horizontal:" + this.posicion_horizontal + ";mso-posicion-vertical:" + this.posicion_vertical + ";mso-posicion-horizontal-relativa:" + this.posicion_horizontal_relativa + ";mso-posicion-vertical-relativa:" + this.posicion_vertical_relativa;
        }
    }
    public static void main(String[] args) throws IOException, InvalidFormatException {
        // Leer documento
        XWPFDocument doc = new XWPFDocument(new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\prueba.docx")));
        
        // Leer imagen
        FileInputStream is = new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\2.jpg"));
        
        // Añadir imagen de marca de agua
        XWPFHeader header = doc.createHeader(HeaderFooterType.DEFAULT);
        // Añadir imagen, obtener ID de la imagen
        String idImagen = header.addPictureData(is, XWPFDocument.PICTURE_TYPE_PNG);
        if (header.getParagraphs().size() == 0) {
            header.createParagraph();
        }
        CTP ctp = header.getParagraphArray(0).getCTP();
        CTR ctr = ctp.addNewR();
        CTPicture pict = ctr.addNewPict();
        CTGroup grupo = CTGroup.Factory.newInstance();
        CTShape forma = grupo.addNewShape();
        forma.setId("MarcadorDeAguaDeWord");
        Estilo estilo = new Estilo("200", "300", "110", "centro", "centro");
        forma.setStyle(estilo.getValorString());
        CTImageData imageData = forma.addNewImagedata();
        imageData.setId2(idImagen);
        pict.set(grupo);

        // Guardar archivo
        String file = "C:\\Users\\DELL\\Desktop\\prueba_generada.docx";
        OutputStream fileOut = new FileOutputStream(file);
        doc.write(fileOut);
    }
}

Insertar texto

El resultado se muestra en la siguiente imagen, se puede definir el tamaño, la posición, el ángulo de rotación, el color, la fuente y un estilo simple.

import com.microsoft.schemas.vml.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STTrueFalse;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class MiClase {
    public static class Estilo {
        public String posicion = "absoluto";
        public String ancho = "100";
        public String alto = "100";
        public String rotacion = "315";
        public String posicion_horizontal = "centro";
        public String posicion_horizontal_relativa = "margen";
        public String posicion_vertical = "centro";
        public String posicion_vertical_relativa = "margen";

        public Estilo(String ancho, String alto, String rotacion, String posicion_horizontal, String posicion_vertical) {
            this.ancho = ancho;
            this.alto = alto;
            this.rotacion = rotacion;
            this.posicion_horizontal = posicion_horizontal;
            this.posicion_vertical = posicion_vertical;
        }

        public String getValorString() {
            return "posicion:" + this.posicion + ";ancho:" + this.ancho + ";alto:" + this.alto + ";rotacion:" + this.rotacion + ";mso-posicion-horizontal:" + this.posicion_horizontal + ";mso-posicion-vertical:" + this.posicion_vertical + ";mso-posicion-horizontal-relativa:" + this.posicion_horizontal_relativa + ";mso-posicion-vertical-relativa:" + this.posicion_vertical_relativa;
        }
    }
    public static void main(String[] args) throws IOException, InvalidFormatException {
        // Leer documento
        XWPFDocument doc = new XWPFDocument(new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\prueba.docx")));

        // Añadir marca de agua
        XWPFHeader header = doc.createHeader(HeaderFooterType.DEFAULT);
        if (header.getParagraphs().size() == 0) {
            header.createParagraph();
        }
        CTP ctp = header.getParagraphArray(0).getCTP();
        CTR ctr = ctp.addNewR();
        CTPicture pict = ctr.addNewPict();
        CTGroup grupo = CTGroup.Factory.newInstance();
        CTShape forma = grupo.addNewShape();
        forma.setId("ObjetoPowerPlusWaterMark");
        Estilo estilo = new Estilo("200", "300", "110", "centro", "centro");
        forma.setStyle(estilo.getValorString());
        forma.setFillcolor("#00FF00");
        forma.setSpid("_x0000_s2051");
        forma.setType("#_x0000_t136");
        forma.setStroked(STTrueFalse.FALSE); // Establecer el texto como sólido
        CTTextPath pathTexto = forma.addNewTextpath();
        pathTexto.setStyle("font-family:" + "\"Arial\"" + ";font-size:" + "1pt"); // Establecer el tipo de letra y tamaño
        pathTexto.setString("Marca de agua");
        pict.set(grupo);

        // Guardar archivo
        String file = "C:\\Users\\DELL\\Desktop\\prueba_generada.docx";
        OutputStream fileOut = new FileOutputStream(file);
        doc.write(fileOut);
    }
}

Versiones antiguas de Word

Apache POI parece no poder completar los requisitos solicitados. Usando Free Spire.Office for Java, esta biblioteca proporciona interfaces convenientes para añadir imágenes y marcas de agua, pero no se puede establecer la posición ni el ángulo de rotación, solo se obtiene el siguiente resultado:

import com.spire.doc.*;
import com.spire.doc.documents.WatermarkLayout;
import java.awt.*;
import java.io.*;

public class MiClase {
    public static void main(String[] args) throws IOException {
        Document doc = new Document();
        doc.loadFromFile("C:\\Users\\DELL\\Desktop\\prueba.doc");
        for(int i=0;i<doc.getSections().getCount();++i){
            Section seccion=doc.getSections().get(i);
            TextWatermark txtWatermark = new TextWatermark();
            txtWatermark.setText("Interno");
            txtWatermark.setFontName("Arial");
            txtWatermark.setFontSize(40);
            txtWatermark.setColor(Color.red);
            txtWatermark.setLayout(WatermarkLayout.Diagonal);
            //txtWatermark.setLayout(WatermarkLayout.Horizontal);
            seccion.getDocument().setWatermark(txtWatermark);
        }

        doc.saveToFile("C:\\Users\\DELL\\Desktop\\prueba_generada.doc",FileFormat.Doc );
    }
}

Se puede insertar una imagen:

import com.spire.doc.*;
import java.io.*;

public class MiClase {
    public static void main(String[] args) throws IOException{
        // Leer documento
        Document doc=new Document(new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\prueba.doc")));
        // Leer imagen
        PictureWatermark imagen=new PictureWatermark("C:\\Users\\DELL\\Desktop\\2.jpg",false);
        // Añadir marca de agua
        imagen.setScaling(100);// Establecer el tamaño
        doc.setWatermark(imagen);
        // Guardar archivo
        doc.saveToFile("C:\\Users\\DELL\\Desktop\\prueba_generada.doc", FileFormat.Doc);
    }
}

Si deseas soportar la rotación de texto, puedes elegir insertar un texto decorativo.

import com.spire.doc.*;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.documents.ShapeType;
import com.spire.doc.fields.ShapeObject;
import com.spire.doc.fields.WordArt;

import java.awt.*;
import java.io.*;

public class MiClase {
    public static void main(String[] args) throws IOException{
        Document doc = new Document();
        doc.loadFromFile("C:\\Users\\DELL\\Desktop\\prueba.doc");
        for(int i=0;i<doc.getSections().getCount();++i){
            Section seccion=doc.getSections().get(i);
            // Definir la posición vertical del texto de la marca de agua
//        float y = (float) (seccion1.getpagesetup().getpagesize().getheight()/3);
            // Añadir texto de marca de agua 1
            HeaderFooter cabecera1 = seccion.getHeadersFooters().getHeader();// Obtener encabezado
            cabecera1.getParagraphs().clear();// Eliminar formato de párrafo existente del encabezado
            Paragraph parrafo1= cabecera1.addParagraph();// Reemplazar párrafo
            // Añadir texto decorativo y configurar el tamaño
            ShapeObject forma = new ShapeObject(doc, ShapeType.Text_Plain_Text);
            forma.setWidth(400);
            forma.setHeight(200);
            forma.setRotation(315);
            forma.setStrokeColor(Color.blue);
            forma.setFillColor(Color.blue);
            WordArt arteTexto=forma.getWordArt();
            arteTexto.setText("Marca de agua muestra");
            arteTexto.setFontFamily("Arial");
            arteTexto.setSize(40);
            forma.setVerticalAlignment(ShapeVerticalAlignment.Center);
            forma.setHorizontalAlignment(ShapeHorizontalAlignment.Center);
            parrafo1.getChildObjects().add(forma);
        }
        doc.saveToFile("C:\\Users\\DELL\\Desktop\\prueba_generada.doc", FileFormat.Doc);
    }
}

POWERPOINT

Como en Excel, solo puedes insertar imágenes como marca de agua, pero PowerPoint tiene el concepto de plantilla, insertar imágenes en la plantilla parece que no se puede eliminar o cambiar, logrando así el efecto de marca de agua.

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.xslf.usermodel.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class MiClase {
    public static void main(String[] args) throws IOException, InvalidFormatException {
        // Leer documento
        XMLSlideShow ppt=new XMLSlideShow(new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\prueba.pptx")));

        // Leer imagen
        FileInputStream is=new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\2.jpg"));
        
        // Añadir marca de agua
        XSLFPictureData pd=ppt.addPicture(is, PictureData.PictureType.PNG);
        Dimension tamanoPagina=ppt.getPageSize();// Obtener el tamaño de página de ppt
        for(XSLFSlide diapositiva:ppt.getSlides())
        {
            XSLFPictureShape pic = diapositiva.getSlideMaster().createPicture(pd);
            pic.setAnchor(new Rectangle((tamanoPagina.width-100)/2,(tamanoPagina.height-200)/2,100,200));
            pic.setRotation(60);
        }
        
        // Guardar archivo
        String file = "C:\\Users\\DELL\\Desktop\\prueba_generada.pptx";
        OutputStream fileOut = new FileOutputStream(file);
        ppt.write(fileOut);
    }
}

Añadir texto Soporta cambios en el tamaño, la posición, el color, la fuente y la rotación.

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.sl.usermodel.Insets2D;
import org.apache.poi.xslf.usermodel.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class MiClase {
    public static void main(String[] args) throws IOException, InvalidFormatException {
        // Leer documento
        XMLSlideShow ppt=new XMLSlideShow(new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\prueba.pptx")));

        // Añadir marca de agua
        Dimension tamanoPagina=ppt.getPageSize();// Obtener el tamaño de página de ppt
        for(XSLFSlide diapositiva:ppt.getSlides())
        {
            XSLFTextBox cajaTexto = diapositiva.getSlideMaster().createTextBox();
            cajaTexto.setHorizontalCentered(true);
            cajaTexto.setInsets(new Insets2D((400-60*2)/2,0,0,0));
            cajaTexto.setAnchor(new Rectangle((tamanoPagina.width-400)/2,(tamanoPagina.height-400)/2,400,400));
            cajaTexto.setRotation(60);
            XSLFTextParagraph p=cajaTexto.addNewTextParagraph();
            XSLFTextRun r=p.addNewTextRun();
            r.setText("Marca de agua");
            r.setFontFamily("SimSun");
            r.setFontColor(Color.BLUE);
            r.setFontSize(60.);
        }

        // Guardar archivo
        String file = "C:\\Users\\DELL\\Desktop\\prueba_generada.pptx";
        OutputStream fileOut = new FileOutputStream(file);
        ppt.write(fileOut);
    }
}

Versiones antiguas de PowerPoint

Apache POI puede implementar esto, incluyendo tamaño, posición y rotación. Inserción de imagen

import org.apache.poi.hslf.usermodel.*;
import org.apache.poi.sl.usermodel.PictureData;
import java.io.*;

public class MiClase {
    public static void main(String[] args) throws IOException{
        HSLFSlideShow ppt = new HSLFSlideShow(new HSLFSlideShowImpl("C:\\Users\\DELL\\Desktop\\prueba.ppt"));

        HSLFPictureData pd = ppt.addPicture(new File("C:\\Users\\DELL\\Desktop\\2.jpg"), PictureData.PictureType.JPEG);

        for(HSLFSlideMaster maestro : ppt.getSlideMasters())
        {
            HSLFPictureShape figuraNueva =maestro.createPicture(pd);
            figuraNueva.setAnchor(new java.awt.Rectangle(100, 100, 300, 200));
            figuraNueva.setRotation(315);
            maestro.addShape(figuraNueva);
        }

        FileOutputStream out = new FileOutputStream("C:\\Users\\DELL\\Desktop\\prueba_generada.ppt");
        ppt.write(out);
        out.close();
    }
}

Inserción de texto Puedes cambiar el tamaño, la posición, el color, la fuente y la rotación.

import org.apache.poi.hslf.usermodel.*;
import java.awt.*;
import java.io.*;

public class MiClase {
    public static void main(String[] args) throws IOException{
        HSLFSlideShow ppt = new HSLFSlideShow(new HSLFSlideShowImpl("C:\\Users\\DELL\\Desktop\\prueba.ppt"));

        for(HSLFSlideMaster maestro : ppt.getSlideMasters())
        {
            HSLFTextBox texto=maestro.createTextBox();
            texto.setText("Texto de la marca de agua");
            texto.setAnchor(new java.awt.Rectangle(100, 100, 300, 200));
            //texto.setRotation(90);
            texto.setTextRotation(200.);
            HSLFTextParagraph p=texto.getTextParagraphs().get(0);
            HSLFTextRun r=p.getTextRuns().get(0);
            r.setFontColor(Color.blue);
            r.setFontFamily("SimHei");
            r.setFontSize(44.);
        }

        FileOutputStream out = new FileOutputStream("C:\\Users\\DELL\\Desktop\\prueba_generada.ppt");
        ppt.write(out);
        out.close();
    }
}

Referencias

https://www.e-iceblue.cn/licensing/install-spirepdf-for-java-from-maven-repository.html

https://www.jianshu.com/p/911d504193cb?u_atoken=f7eda06b-8c47-48bd-b20d-78819784e838&amp;u_asession=01ummDbdI5ZhVuHtco2Kd04rNCk1quh2aoyIYaQ4ZYFzt_4nyx-*6nw6FOs4usXbSVX0KNBwm7Lovlpxjd_P_q4JsKWYrT3W_NKPr8w6oU7K-Dduym2jZxTP5bEXXyXZaEslvTX-jMTLEIhdGFg3rxgWBkFo3NEHBv0PZUm6pbxQU&u_asig=05469NN0m4fsQ_SGn4moWfU4ovWlkzGZg9V00LpxgoNuK_Wg_dwiwIDR-mEox1O6jbRPX82t8ziU_pbLxbG_eiMTaUM4qF9Guii5AT6-NRWV8XO_cPDK4tVYXpxJn4uS4FTlYbOTh3OlfFgucbiekiL3T07AAhdTYlElq9q33oyRv9JS7q8ZD7Xtz2Ly-b0kmuyAKRFSVJkkdwVUnyHAIJzWmDAC4hDrvIG14ZxSLEBpHd0Ou03bz9VxfcI8PcSTku6FPw117USKdEPc8n7HkzU-3h9VXwMyh6PgyDIVSG1W9Zl2S9zvPM4ZeUYgtHa-zKmAxB0TMadCqhaHIZUDczZ5WZmH6xhh-aV-3VTCMa9ktFcuorl3fuDZw*-F3P55rkmWspDxyAEEo4kbsryBKb9Q&u_aref=tWpHGvnd%2BBIXfMdKtkBVrETkhk4%3D

https://lantingshuxu.github.io/java/java-%E4%BD%BF%E7%94%A8POI%E5%AE%9E%E7%8E%B0%E4%B8%BAword%E6%96%87%E6%A1%A3-docx-%E6%B7%BB%E5%8A%A0%E6%B0%B4%E5%8D%B0/

https://blog.csdn.net/qq_42835445/article/details/118311354

https://www.10qianwan.com/articledetail/850224.html

https://www.jb51.net/article/205710.htm

https://blog.csdn.net/m0_66876551/article/details/124307320

https://ask.csdn.net/questions/7496162

Publicado el 9-6 17:33