POI 读取doxc 并用图片替换文中的文字

POI 在java中用的越来越多,自己记下来并且分享给有需要的人  希望大家越来越好

一、poi读取docx的操作 (maven依赖在本页末)

1、先读取本地word.docx

 //读取文件docx 文件(本地文件) 
 OPCPackage opcPackage = POIXMLDocument.openPackage("D:\\develop\\demo.docx");
 //用于获取docx文件的表格数据以及文本数据  详细看源码
 XWPFDocument doc = new XWPFDocument(opcPackage);

2、获取word中table以外的文本数据 并以图片替换

//获取所有段落  读取dcox文件文字
        List<XWPFParagraph> paragraphList1 = doc.getParagraphs();
        //遍历段落
        for (int p = 0; p < paragraphList1.size(); p++) {
            //获取所有文本对象
            List<XWPFRun> runs = paragraphList1.get(p).getRuns();
            //遍历所有文本对象
            for (int r = 0; r < runs.size(); r++) {
                String text = runs.get(r).getText(0);
                if (text != null) {
                    //判断文本对象是否包含图片占位符 ${pic1}是文本中的占位符
                    if (text.contains("${pic1}")) {
                        //换行
                        runs.get(r).addBreak();
                        //图片的位置 后期可以换成文件地址   读取图片 然后再替换
                        String picPath="D:\\develop\\3.png";
               //EMU值是和mm有一种换算比例  runs.get(r).addPicture(
new FileInputStream(picPath), Document.PICTURE_TYPE_PNG,picPath, Units.toEMU(124), Units.toEMU(34)); runs.get(r).addBreak(BreakType.TEXT_WRAPPING); //删除旧的文本对象,就是删除占位符 //paragraphList.get(p).removeRun(0); //插入图片后,图片和占位符变成一个文本对象了,removeRun连图片一起删了,使用setText runs.get(r).setText("",0); } } } }

3、读取Table中的数据

 //读取word (docx)中table表格数据
        List<XWPFTable> tables = doc.getTables();
        for (XWPFTable table : tables) {
            for (XWPFTableRow row : table.getRows()) {
                List<XWPFTableCell> tableCells = row.getTableCells();
                for (XWPFTableCell tableCell : tableCells) {
                    List<XWPFParagraph> paragraphList = tableCell.getParagraphs();
                    for (int p = 0; p < paragraphList.size(); p++) {
                        //获取所有文本对象
                        List<XWPFRun> runs = paragraphList.get(p).getRuns();
                        //遍历所有文本对象
                        for (int r = 0; r < runs.size(); r++) {
                            String text = runs.get(r).getText(0);
                            if (text != null) {
                                //判断文本对象是否包含图片占位符 ${pic1}是文本中的占位符
                                if (text.contains("${pic1}")) {
                                    //换行
                                    //runs.get(r).addBreak();
                                    runs.get(r).setText("",0);
                                    //图片的位置 后期可以换成文件地址   读取图片 然后再替换
                                    URL url = new URL("http://****:19000/group1/M00/00/0E/wKgU5mO350WASJd3AAAnb3N_f9w423.png");
                                    InputStream inputStream = url.openStream();
                                    String picPath="D:\\develop\\3.png";
                                    runs.get(r).addPicture(new FileInputStream(picPath), Document.PICTURE_TYPE_PNG,picPath, 612000, 216000);
                                    //换行
                                    //runs.get(r).addBreak(BreakType.TEXT_WRAPPING);
                                }
                            }
                        }
                    }
                }
            }
        }

4、最后写出或者重新上传

//获取所有段落  读取doc文件  有需要可以自己用上传接口  
doc.write(new FileOutputStream("D:\\develop\\test1.docx"));
//document和MultipartFile转换 用fastdfs上传到自己想要的位置
MultipartFile multipartFile = xwpfDocumentToCommonsMultipartFile(doc, "a.docx");

二、有些项目可能是需要读取doc文件  目前POI好像不支持doc 需要将doc转换成docx (仅代表个人观点,没深入研究)

  1、读取doc文件(本地文件)需要转换

//读取文件doc文件
String path="D:\\develop\\5566.doc";
//读取doc文件
com.spire.doc.Document document = new com.spire.doc.Document();
//加载doc文件
document.loadFromFile(path);
//强制转换成docx文件
document.saveToFile(path, FileFormat.Docx_2013);
XWPFDocument doc = new XWPFDocument(new FileInputStream(path));

  2、读取文本并替换文字

  

//加载docx文档
        List<XWPFParagraph> paragraphList = doc.getParagraphs();
        //遍历段落
        for (int p = 0; p < paragraphList.size(); p++) {
            //获取所有文本对象
            List<XWPFRun> runs = paragraphList.get(p).getRuns();
            //遍历所有文本对象
            for (int r = 0; r < runs.size(); r++) {
                String text = runs.get(r).getText(0);
                if (text != null) {
                    //判断文本对象是否包含图片占位符 ${pic1}是文本中的占位符
                    if (text.contains("${pic1}")) {
                        //换行
                        runs.get(r).addBreak();
                        //图片的位置 后期可以换成文件地址   读取图片 然后再替换
                        String picPath = "D:\\develop\\3.png";
                        runs.get(r).addPicture(new FileInputStream(picPath), Document.PICTURE_TYPE_PNG, picPath, Units.toEMU(124), Units.toEMU(34));
                        runs.get(r).addBreak(BreakType.TEXT_WRAPPING);
                        //删除旧的文本对象,就是删除占位符
                        //paragraphList.get(p).removeRun(0);
                        //插入图片后,图片和占位符变成一个文本对象了,removeRun连图片一起删了,使用setText
                        runs.get(r).setText("", 0);
                    }
                }
            }
        }

3、读取docx中table的文本数据  复用第一个的第三个即可

4、写出同第一个最后一步

三、添加图片的浮动属性

 1、有些项目需要是照片浮动在文字之上不占用 其格式(上代码) 在添加照片后面 增加以下代码即可

   CTDrawing drawingArray = runs.get(r).getCTR().getDrawingArray(0);
                        CTGraphicalObject graphicalobject = drawingArray.getInlineArray(0).getGraphic();
                        CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "Seal" + 12,
                                1188000, 324000,//图片大小
                                4860000, -122000, false);
                        drawingArray.setAnchorArray(new CTAnchor[]{anchor});//添加浮动属性
                        drawingArray.removeInline(0);

2、主要方法如下:

 /**
     *
     * @param ctGraphicalObject CTGraphicalObject
     * @param deskFileName String  没啥作用  我还没研究出来
     * @param width int  宽 (长度/mm * 36000)
     * @param height int 高 (长度/mm * 36000)
     * @param leftOffset int  左偏偏移量 (长度/mm * 36000)
     * @param topOffset int  右偏移量 (长度/mm * 36000)
     * @param behind boolean  文字上方还是下方
     * @return CTAnchor
     * @author ASUS
     * @since 2023/1/9 10:08
     */
    public static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject, String deskFileName, int width, int height, int leftOffset, int topOffset, boolean behind) {
        String anchorXML =""
                +"<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
                +"   <wp:simplePos x=\"0\" y=\"0\"/>"
                +"   <wp:positionH relativeFrom=\"column\">"
                +"      <wp:posOffset>"+ leftOffset + "</wp:posOffset>"
                +"   </wp:positionH>"
                +"   <wp:positionV relativeFrom=\"line\">"
                +"      <wp:posOffset>"+ topOffset +"</wp:posOffset>"
                +"   </wp:positionV>"
                +"   <wp:extent cx=\"" + width + "\" cy=\"" + height + "\"/>"
                +"   <wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
                +"   <wp:wrapNone/>"
                +"   <wp:docPr id=\"1\" name=\"Drawing 0\" descr=\"" +deskFileName+ "\"/><wp:cNvGraphicFramePr/>"
                +"</wp:anchor>";
        try {
            CTDrawing drawing = CTDrawing.Factory.parse(anchorXML);
            CTAnchor anchor = drawing.getAnchorArray(0);
            anchor.setGraphic(ctGraphicalObject);
            return anchor;
        } catch (XmlException e) {
            e.printStackTrace();
            return null;
        }
    }

四、主要pom依赖(poi依赖自行在网上查找4.0版本就行)

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>e-iceblue</groupId>
    <artifactId>spire.doc.free</artifactId>
    <version>3.9.0</version>
</dependency>

五、本文引用地址

1、https://www.cnblogs.com/keke12345/p/14350001.html

2、https://blog.csdn.net/qq_38974638/article/details/119844636

还有几个地址忘了  找不到了

                                                                                    ----栖息动物

 

posted @ 2023-01-09 14:41  栖息动物  阅读(428)  评论(0)    收藏  举报