zoukankan      html  css  js  c++  java
  • poi-word导出,导出多图片到word

    一、添加依赖

            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-scratchpad</artifactId>
                <version>3.15</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.15</version>
            </dependency>
            <dependency>
                <groupId>com.deepoove</groupId>
                <artifactId>poi-tl</artifactId>
                <version>1.0.0</version>
            </dependency>
    

      

    二、工具类

    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.text.SimpleDateFormat;
    import java.util.*;
    import com.deepoove.poi.XWPFTemplate;
    import com.deepoove.poi.data.PictureRenderData;
    import com.hdvon.nmp.vcase.config.AppConfig;
    import com.hdvon.nmp.vcase.helper.SpringHelper;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.poi.xwpf.usermodel.*;
    import org.springframework.util.FileCopyUtils;
    
    import javax.imageio.ImageIO;
    
    /**
     * 适用于word 2007
     * poi 版本 3.7
     */
    @Slf4j
    public class WordHelper {
    
        /***
         * 写入书签内容、图片t
         * @param oldFileName 旧的文件名
         * @param filePath 模板文件路径
         * @param map 指定写入书签参数
         */
        public String export(String oldFileName,String filePath, Map<String, Object> oldmap){
            AppConfig appConfig = SpringHelper.getBean(AppConfig.class);
            String folder=appConfig.getBasePath()+appConfig.getWordPath();
            try {
                Map<String, Object> map=new HashMap<>();
                for (String key:oldmap.keySet()){
                    map.put("${"+key+"}",oldmap.get(key));
                }
                if(StringUtils.isBlank(folder))return "";
                String newFileFolder=folder+new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                File newFile=new File(newFileFolder);
                if(!newFile.exists()){
                    newFile.mkdir();
                }
                String fileName=new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"\"+oldFileName;
                File outFile=new File(folder+fileName);
                //复制一份模板
                String copyPath=folder+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"\"+"template.docx";
                File copyFile=new File(copyPath);
                FileCopyUtils.copy(new File(filePath),copyFile);
                //写入文字到doc
                OutputStream outputStream = null;
                outputStream = new FileOutputStream(outFile);
                XWPFDocument doc=WordUtil.generateWord(map,copyPath);
                doc.write(outputStream);
                outputStream.flush();
                outputStream.close();
                doc.close();
                //写入图片到doc
                String picUrl = (String)map.get("${picUrl}");
                String[] urls = picUrl.split(";");
                int size=urls.length;
                FileInputStream inputStream=new FileInputStream(outFile);
                XWPFDocument doc1=new XWPFDocument(inputStream);
                outputStream = new FileOutputStream(outFile);
                XWPFParagraph lastParagraph = doc1.getLastParagraph();
                for(int i=1;i<=size;i++){
                    XWPFRun run = lastParagraph.createRun();
                    run.setText("{{@localhostPicture"+i+"}}");
                    lastParagraph.addRun(run);
    
                }
                doc1.write(outputStream);
                inputStream.close();
                outputStream.close();
                doc1.close();
    
    
               Map<String,Object> datas=new HashMap<String,Object>();
               File imgFile=null;
               FileInputStream imgInputStream=null;
               BufferedImage image=null;
                for(int i=0;i< urls.length;i++){
                    String url=urls[i];
                    url=appConfig.getBasePath()+url;
                    imgFile=new File(url);
                    if(!imgFile.exists()) continue;
                    imgInputStream=new FileInputStream(imgFile);
                    image= ImageIO.read(imgInputStream);
                    if(StringUtils.isNotBlank(url)) {
                        datas.put("localhostPicture" + (i + 1), new PictureRenderData(image.getWidth(), image.getHeight(), url));
                    }
                }
    
                XWPFTemplate template=XWPFTemplate.compile(outFile).render(datas);
                FileOutputStream out1=new FileOutputStream(outFile);
                template.write(out1);
                out1.flush();
                out1.close();
                template.close();
                imgInputStream.close();
            }catch (Exception e){
                e.printStackTrace();
            }
            return appConfig.getWordPath()+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"/"+oldFileName;
        }
    }
    

      

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import org.apache.poi.POIXMLDocument;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.openxml4j.opc.OPCPackage;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    import org.apache.poi.xwpf.usermodel.XWPFTable;
    import org.apache.poi.xwpf.usermodel.XWPFTableCell;
    import org.apache.poi.xwpf.usermodel.XWPFTableRow;
    import org.apache.xmlbeans.XmlException;
    import org.apache.xmlbeans.XmlToken;
    import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
    import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
    import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
    
    /**
     * 适用于word 2007
     * poi 版本 3.7
     */
    public class WordUtil {
    
        /**
         * 根据指定的参数值、模板,生成 word 文档
         *
         * @param param    需要替换的变量
         * @param template 模板
         */
        public static XWPFDocument generateWord(Map<String, Object> param, String template) {
            XWPFDocument doc = null;
            try {
                OPCPackage pack = POIXMLDocument.openPackage(template);
                doc = new CustomXWPFDocument(pack);
                if (param != null && param.size() > 0) {
    
                    //处理段落
                    List<XWPFParagraph> paragraphList = doc.getParagraphs();
                    processParagraphs(paragraphList, param, doc);
    
                    //处理表格
                    Iterator<XWPFTable> it = doc.getTablesIterator();
                    while (it.hasNext()) {
                        XWPFTable table = it.next();
                        List<XWPFTableRow> rows = table.getRows();
                        for (XWPFTableRow row : rows) {
                            List<XWPFTableCell> cells = row.getTableCells();
                            for (XWPFTableCell cell : cells) {
                                List<XWPFParagraph> paragraphListTable = cell.getParagraphs();
                                processParagraphs(paragraphListTable, param, doc);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return doc;
        }
    
        /**
         * 处理段落
         *
         * @param paragraphList
         * @throws FileNotFoundException
         * @throws InvalidFormatException
         */
        public static void processParagraphs(List<XWPFParagraph> paragraphList, Map<String, Object> param, XWPFDocument doc) throws InvalidFormatException, FileNotFoundException {
            if (paragraphList != null && paragraphList.size() > 0) {
                for (XWPFParagraph paragraph : paragraphList) {
                    List<XWPFRun> runs = paragraph.getRuns();
                    for (XWPFRun run : runs) {
                        String text = run.getText(0);
                        if (text != null) {
                            boolean isSetText = false;
                            for (Entry<String, Object> entry : param.entrySet()) {
                                String key = entry.getKey();
                                if (text.indexOf(key) != -1) {
                                    isSetText = true;
                                    Object value = entry.getValue();
                                    if (value instanceof Object) {//文本替换
                                        text = text.replace(key, value.toString());
                                    } else if (value instanceof Map) {    //图片替换
                                        text = text.replace(key, "");
                                        Map pic = (Map) value;
                                        int width = Integer.parseInt(pic.get("width").toString());
                                        int height = Integer.parseInt(pic.get("height").toString());
                                        int picType = getPictureType(pic.get("type").toString());
                                        String byteArray = (String) pic.get("content");
    
    
                                        //ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);
    
                                        //int ind = doc.getAllPictures().size() - 1;
                                        //doc.createPicture(ind, width , height,paragraph);
                                        CTInline inline = run.getCTR().addNewDrawing().addNewInline();
                                        insertPicture(doc, byteArray, inline, width, height);
    
                                    }
                                }
                            }
                            if (isSetText) {
                                run.setText(text, 0);
                            }
                        }
                    }
                }
            }
        }
    
        /**
         * 根据图片类型,取得对应的图片类型代码
         *
         * @param picType
         * @return int
         */
        private static int getPictureType(String picType) {
            int res = CustomXWPFDocument.PICTURE_TYPE_PICT;
            if (picType != null) {
                if (picType.equalsIgnoreCase("png")) {
                    res = CustomXWPFDocument.PICTURE_TYPE_PNG;
                } else if (picType.equalsIgnoreCase("dib")) {
                    res = CustomXWPFDocument.PICTURE_TYPE_DIB;
                } else if (picType.equalsIgnoreCase("emf")) {
                    res = CustomXWPFDocument.PICTURE_TYPE_EMF;
                } else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) {
                    res = CustomXWPFDocument.PICTURE_TYPE_JPEG;
                } else if (picType.equalsIgnoreCase("wmf")) {
                    res = CustomXWPFDocument.PICTURE_TYPE_WMF;
                }
            }
            return res;
        }
    
        /**
         * 将输入流中的数据写入字节数组
         *
         * @param in
         * @return
         */
        public static byte[] inputStream2ByteArray(InputStream in, boolean isClose) {
            byte[] byteArray = null;
            try {
                int total = in.available();
                byteArray = new byte[total];
                in.read(byteArray);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (isClose) {
                    try {
                        in.close();
                    } catch (Exception e2) {
                        System.out.println("关闭流失败");
                    }
                }
            }
            return byteArray;
        }
    
        /**
         * insert Picture
         *
         * @param document
         * @param filePath
         * @param inline
         * @param width
         * @param height
         * @throws InvalidFormatException
         * @throws FileNotFoundException
         */
        private static void insertPicture(XWPFDocument document, String filePath,
                                          CTInline inline, int width,
                                          int height) throws InvalidFormatException,
                FileNotFoundException {
            document.addPictureData(new FileInputStream(filePath), XWPFDocument.PICTURE_TYPE_PNG);
            int id = document.getAllPictures().size() - 1;
            final int EMU = 9525;
            width *= EMU;
            height *= EMU;
            String blipId =
                    document.getAllPictures().get(id).getPackageRelationship().getId();
            String picXml = getPicXml(blipId, width, height);
            XmlToken xmlToken = null;
            try {
                xmlToken = XmlToken.Factory.parse(picXml);
            } catch (XmlException xe) {
                xe.printStackTrace();
            }
            inline.set(xmlToken);
            inline.setDistT(0);
            inline.setDistB(0);
            inline.setDistL(0);
            inline.setDistR(0);
            CTPositiveSize2D extent = inline.addNewExtent();
            extent.setCx(width);
            extent.setCy(height);
            CTNonVisualDrawingProps docPr = inline.addNewDocPr();
            docPr.setId(id);
            docPr.setName("IMG_" + id);
            docPr.setDescr("IMG_" + id);
        }
    
        /**
         * get the xml of the picture
         *
         * @param blipId
         * @param width
         * @param height
         * @return
         */
        private static String getPicXml(String blipId, 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="" + 0 +
                            "" 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="0" y="0"/>" +
                            "               <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;
        }
    }
    

      

  • 相关阅读:
    BZOJ2821 作诗(Poetize) 【分块】
    BZOJ2724 蒲公英 【分块】
    Codeforces 17E Palisection 【Manacher】
    BZOJ2565 最长双回文串 【Manacher】
    Codeforces 25E Test 【Hash】
    CODEVS3013 单词背诵 【Hash】【MAP】
    HDU2825 Wireless Password 【AC自动机】【状压DP】
    HDU2896 病毒侵袭 【AC自动机】
    HDU3065 病毒侵袭持续中【AC自动机】
    HDU2222 Keywords Search 【AC自动机】
  • 原文地址:https://www.cnblogs.com/tinyj/p/9802535.html
Copyright © 2011-2022 走看看