Java poi 去除word文档水印

      一开始使用的spire.doc去除水印是收费的,虽然说有免费的,但是呢也有限制最多500字来着。后面尝试用poi去除水印,咦把还不错然后还没有限制什么的。如你有钱的话我也不会阻止你使用spire.doc商业版去除水印。但是我还是觉得免费的更香一点。spire.doc的话这里我就不多讲了。我提供poi就是,话不多说上代码。

一、首先添加依赖

 <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>4.1.2</version>
 </dependency>
 <dependency>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-lang3</artifactId>
 </dependency>

二、工具类




import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;

public class WordUtil {
    /**
     * 段落
     */
    private static final String P_0 = "本次检测风险项分布如下图:";
    private static final String P_1 = "风险项分布图:";
    private static final String P_2 = "本次检测风险项检测占比如下图:";
    private static final String P_3 = "风险项检测占比图:";
    private static final String P_4 = "加固壳识别:";
    private static final String P_5 = "第三方SDK检测:";
    /**
     * 表格
     */
    private static final String TB_0 = "SDK名称";
    private static final String TB_1 = "权限";
    private static final String TB_2 = "加固壳识别";
    private static final String TB_3 = "权限详情";
    private static final String TB_4 = "风险详情";

    public static void main(String[] args) throws Exception {
        press("掌上工程", "D:\\内蒙古和校园教师版_android_安全评测完整报告_2021-05-07.docx","D:\\a.docx");
    }


    public static void press(String appName, String filePath,String outPath) throws Exception {

        // 延迟解析比率
        ZipSecureFile.setMinInflateRatio(-1.0d);
        InputStream is = new FileInputStream(filePath);
        XWPFDocument doc = new XWPFDocument(is);
        CTBody body = doc.getDocument().getBody();
        body.getPArray(5).getRArray(0).getTArray(0).setStringValue("中国移动自有APP安全评估报告");
        body.getPArray(6).getRArray(0).getTArray(0).setStringValue(appName);
        // 删除图片
        doc.getParagraphs().forEach(WordUtil::removeParagraphPicture);

        XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
        XWPFHeader headers = headerFooterPolicy.getDefaultHeader();
        // 获取页眉
        List<XWPFHeader> headerList = doc.getHeaderList();
        for (XWPFHeader xwpfHeader : headerList) {
            // 清除页眉页脚,并清除水印
            xwpfHeader.clearHeaderFooter();
        }
        XWPFParagraph paragraph = headers.createParagraph();
        // 页眉左对齐
        paragraph.setAlignment(ParagraphAlignment.LEFT);
        // 页眉底部边框
        paragraph.setBorderBottom(Borders.HEART_GRAY);
        XWPFRun run = paragraph.createRun();
        // 设置页眉
        run.setText("hutools ");

        // 移除第一个图片控件,
        body.removeSdt(0);
        // 表格里的第三方SDK
        List<String> sdkList = Lists.newArrayList();
        // 需要移除的表格下标
        List<Integer> tbIndex = Lists.newArrayList();
        List<XWPFTable> tables = doc.getTables();
        for (int i = 0; i < tables.size(); i++) {
            XWPFTable table = tables.get(i);
            if (i == 1) {
                // 往基本信息表格加一行
                addRow(doc, table);
            } else {
                // 其他表格删除风险详情
                delRow(table);
            }
            // 表格第一行
            XWPFTableRow row = table.getRow(0);
            // 行列数
            int size = row.getTableCells().size();
            // 表格行超过一列
            if (size > 1) {
                // 第一列文本值
                String text0 = row.getCell(0).getText();
                // 第二列文本值
                String text1 = row.getCell(1).getText();
                if (TB_0.equals(text0)) {
                    System.out.println(text0);
                    tbIndex.add(i);
                    sdkList.add(text1);
                }
                if (TB_1.equals(text0) && size == 5) {
                    System.out.println(text0);
                    tbIndex.add(i);
                }
                if (TB_2.equals(text1)) {
                    tbIndex.add(i);
                }
            } else {
                String text = row.getCell(0).getText();
                if (TB_3.equals(text)) {
                    System.out.println("0\t" + text);
                    tbIndex.add(i);
                }
            }
        }
        // 段落值清空 (第一页)
        body.getPArray(14).getRArray(0).getTArray(0).setStringValue(null);
        // 段落值清空 (第一页)
        body.getPArray(15).getRArray(0).getTArray(0).setStringValue(null);
        // 移除的段落
        List<Integer> removePs = Lists.newArrayList();
        // 所有段落
        List<CTP> pList = body.getPList();
        for (int i = 0; i < pList.size(); i++) {
            List<CTR> rList = pList.get(i).getRList();
            for (CTR ctr : rList) {
                if (ctr.sizeOfTArray() > 0) {
                    String value = ctr.getTArray(0).getStringValue();
                    if (StringUtils.contains(value, P_0) || StringUtils.contains(value, P_1)
                            || StringUtils.contains(value, P_2) || StringUtils.contains(value, P_3)
                    ) {
                        removePs.add(i);
                        System.out.println(value + "\t" + i);
                        break;
                    } else if (StringUtils.contains(value, P_4) || StringUtils.contains(value, P_5)) {
                        removePs.add(i);
                        System.out.println(value + "\t" + i);
                        break;
                    } else if (CollectionUtils.containsAny(sdkList, StringUtils.substringAfter(value, "."))) {
                        removePs.add(i);
                        System.out.println("sdk++++++++++:" + value + i);
                        break;
                    }
                }
            }
        }

        // 移除不需要的段落
        int p = 0;
        for (int i = 0; i < removePs.size(); i++) {
            if (i == 0) {
                body.removeP(removePs.get(i));
            } else {
                body.removeP(removePs.get(i) - (1 + p));
                p++;
            }
        }
        // 移除不需要的表格
        int t = 0;
        for (Integer index : tbIndex) {
            if (index == 3) {
                body.removeTbl(index);
            } else {
                body.removeTbl(index - (1 + t));
                t++;
            }
        }
        //输出文件
        FileOutputStream os = new FileOutputStream(outPath);
        doc.write(os);
        doc.close();
        os.close();
        System.out.println("输出的路径:"+outPath);
//        System.out.println("文件名为:"+name);
    }

    /**
     * 移除图片
     */
    private static void removeParagraphPicture(XWPFParagraph paragraph) {
        List<XWPFRun> runs = paragraph.getRuns();
        try {
            for (XWPFRun run : runs) {
                List<XWPFPicture> pics = run.getEmbeddedPictures();
                if (pics.size() > 0) {
                    paragraph.removeRun(0);
                }
            }
        } catch (Exception ignored) {

        }
    }

    /**
     * 基础信息表格加一栏 是否加固
     */
    private static void addRow(XWPFDocument doc, XWPFTable table) {
        // 获取加固识别
        String text = doc.getTableArray(3).getRow(3).getCell(1).getText();
        // 表格加一行
        XWPFTableRow row = table.createRow();
        XWPFTableCell cell = row.getCell(0);
        XWPFRun xwpfRun = cell.getParagraphArray(0).createRun();
        xwpfRun.setBold(true);
        xwpfRun.setText("是否加固");
        cell.setColor(table.getRow(0).getCell(0).getColor());
        row.getCell(1).setText("安全".equals(text) ? "是" : "否");
    }

    /**
     * 移除表格 风险详情
     */
    private static void delRow(XWPFTable xwpfTable) {
        List<XWPFTableRow> rows = xwpfTable.getRows();
        for (int j = 0; j < rows.size(); j++) {
            XWPFTableRow tableRow = rows.get(j);
            if (StringUtils.contains(tableRow.getCell(0).getText(), TB_4)) {
                xwpfTable.removeRow(j);
                break;
            }
        }
    }

}

三、效果图。没有去除水印之前

 

去除水印之后:

 

这个是根据你自己word文档来更改自己需要某一些东西,不是说拿来就不更改就可以用的

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是Java POI 3.10 Word水印代码示例: ``` import java.io.*; import org.apache.poi.xwpf.usermodel.*; import org.apache.poi.util.*; import org.apache.poi.openxml4j.opc.*; import org.apache.poi.xwpf.model.*; import org.apache.xmlbeans.*; public class WordWatermark { public static void main(String[] args) throws Exception { // 创建一个新的Word文档 XWPFDocument doc = new XWPFDocument(); // 添加文档内容 XWPFParagraph para = doc.createParagraph(); XWPFRun run = para.createRun(); run.setText("Hello World!"); // 添加水印 String watermarkText = "Confidential"; addWatermark(doc, watermarkText); // 保存Word文档 FileOutputStream out = new FileOutputStream("test.docx"); doc.write(out); out.close(); doc.close(); } // 添加水印 public static void addWatermark(XWPFDocument doc, String watermarkText) throws Exception { // 创建水印段落 XWPFParagraph watermarkPara = doc.createParagraph(); watermarkPara.setAlignment(ParagraphAlignment.CENTER); watermarkPara.setVerticalAlignment(TextAlignment.CENTER); // 创建水印文字 XWPFRun watermarkRun = watermarkPara.createRun(); watermarkRun.setText(watermarkText); watermarkRun.setColor("C0C0C0"); watermarkRun.setFontSize(100); // 获取页面大小 CTPageSz pageSize = doc.getDocument().getBody().getSectPr().getPgSz(); // 计算水印位置 int posX = (pageSize.getW().intValue() - watermarkRun.getText().length() * 50) / 2; int posY = (pageSize.getH().intValue() - 100) / 2; // 创建水印图片 byte[] rgb = new byte[] { (byte)192, (byte)192, (byte)192 }; XWPFRun run = doc.createParagraph().createRun(); String blipId = run.getCTR().addNewPict().addNewBlipFill().addNewBlip().getEmbed(); File imageFile = createImage(rgb); FileInputStream fis = new FileInputStream(imageFile); int picInd = doc.addPicture(fis, XWPFDocument.PICTURE_TYPE_PNG); fis.close(); String picXml = getPicXml(blipId, picInd, posX, posY, 100, 100); CTInline inline = CTInline.Factory.parse(picXml); run.getCTR().set(inline); // 设置水印透明度 CTPicture ctPicture = run.getCTR().getPictArray(0); CTBlipFillProperties ctBlipFillProperties = ctPicture.getBlipFill(); CTAlphaTransform ctAlphaTransform = ctBlipFillProperties.addNewAlphaBiLevel(); ctAlphaTransform.setVal(80000); } // 创建水印图片 public static File createImage(byte[] rgb) throws Exception { BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = image.createGraphics(); graphics.setColor(new Color(rgb[0], rgb[1], rgb[2])); graphics.fillRect(0, 0, 100, 100); File file = File.createTempFile("watermark", ".png"); ImageIO.write(image, "png", file); return file; } // 获取水印图片XML public static String getPicXml(String blipId, int picInd, int posX, int posY, int width, int height) { String picXml = "" + "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" + "<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" + "<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" + "<pic:nvPicPr>" + "<pic:cNvPr id=\""+picInd+"\" name=\"Generated\"/>" + "<pic:cNvPicPr/>" + "</pic:nvPicPr>" + "<pic:blipFill>" + "<a:blip r:embed=\""+blipId+"\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" + "<a:stretch>" + "<a:fillRect/>" + "</a:stretch>" + "</pic:blipFill>" + "<pic:spPr>" + "<a:xfrm>" + "<a:off x=\""+posX+"\" y=\""+posY+"\"/>" + "<a:ext cx=\""+width+"\" cy=\""+height+"\"/>" + "</a:xfrm>" + "<a:prstGeom prst=\"rect\">" + "<a:avLst/>" + "</a:prstGeom>" + "</pic:spPr>" + "</pic:pic>" + "</a:graphicData>" + "</a:graphic>"; return picXml; } } ``` 在示例,我们创建了一个新的Word文档,并添加了一些文本内容。然后,我们调用了addWatermark方法来添加水印。在该方法,我们首先创建了一个水印段落,然后创建了一个包含水印文字的运行。接下来,我们使用CTPageSz类获取页面大小,并计算出水印的位置。然后,我们创建了一个水印图片,并将其添加到Word文档。最后,我们使用CTAlphaTransform类设置水印的透明度。 需要注意的是,水印的位置和大小可能需要根据不同的Word文档进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值