java 使用jacob+jacob工具類實現html頁面導出word


接着上一篇使用jacob導出html頁面至word中產生的問題,在網上又找到了其他解決辦法,該文作者是使用MsOfficeGeneratorUtils工具類實現了html->word。

項目需求:將html頁面導出到word,頁面是由json配置文件讀取后台拼成的頁面,頁面中圖是使用echarts產生。

缺陷:由於頁面是動態配置的,所以不適合使用配置模板的方式導出到word

依賴:

<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.8.3</version>
        </dependency>

項目中使用了jacob,但我並沒有使用maven添加該jacob的依賴,因為添加jacob依賴不僅要加jar包還要在項目中添加jacob的dll文件。

如果你是像上一篇文章那樣:

你要下載jacob(要和自己項目里maven dependence中的版本一致),在找到下載jacob里的jacob-***-x64.dll【和操作系統版本一致】,
將這個文件依次貼到E:\jdk\jre1.8\bin和E:\jdk\1.8\jre\bin【否則會報錯:no jacob-***-x64 in java.library.path】

 會導致的問題在這里說一下:

當你更改項目讓tomcat自動重啟時,再次導出會報錯:java.lang.UnsatisfiedLinkError: Native Library D:\Java\jdk1.7\jre\bin\jacob-1.17-x86.dll already loaded in another classloader

 

解決辦法:

只需要將jacob-1.14.3-x64.dll拷貝到tomcat的bin目錄下,並把你下載的jacob.jar拷貝到tomcat的lib即可,不需要那么麻煩的貼到jdk和jre目錄下了,在eclipse里也不需要配置。(不要使用maven獲取的jacob.jar。自己將手動下載的jar添加到項目中和tomcat的lib中)

 如下三張圖:

  

依賴和dll文件放好,下面就開始寫代碼導出了

=======================從前台開始====================

【不能使用ajax請求去下載文件,在此我犯了這個錯誤】-原因是:

使用ajax不能實現文件的下載:ajax方式下載文件時無法觸發瀏覽器打開保存文件對話框,也就無法將下載的文件保存到硬盤上!ajax方式請求的數據只能存放在javascipt內存空間,可以通過javascript訪問,但是無法保存到硬盤,因為javascript不能直接和硬盤交互,否則將是一個安全問題。

 解決辦法使用模擬表單提交同步方式下載文件,將你要傳遞的數據通過input方式傳遞,java后台用request.getParameter方式獲取

參考代碼:

// 模擬表單提交同步方式下載文件
    // 能夠彈出保存文件對話框
    function jumpDownload() {
        var url = "http://localhost:8080/exportWord";
        var fileName = "testAjaxDownload.txt";
        var form = $("<form></form>").attr("action", url).attr("method", "post");
        form.append($("<input></input>").attr("type", "hidden").attr("name", "fileName").attr("value", fileName));
        form.appendTo('body').submit().remove();
    }

---------------------
作者:suveng 
來源:CSDN 
原文:https://blog.csdn.net/qq_37933685/article/details/79980925?utm_source=copy 
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

 項目實際代碼:【參考代碼已經紅標出】

/**
     * 導出按鈕
     * 
     * @return
     */
    @SuppressWarnings("null")
    public static Div exportHtml() {
        Div d = new Div();
        String div = "<button id=\"export_btn\" class=\"btn btn-primary\" style=\"margin-left:20px\">導出</button>";
        StringBuilder script = new StringBuilder();
        script.append("var echartArr = new Array();");
        // 替換span查詢條件
        script.append("function giveSpanData() {" + "$.each($('#selector .form-group'),function(index,value) {"
                + "$(this).children('.hide-span').eq(0).html($(this).find('input').attr('value'));" + "});" + "};");
        // 點擊事件
        script.append("$(\"#export_btn\").click(function() {");
        script.append("giveSpanData();");
        script.append("var markup = $(\"#export\").clone();");
        // 設置布局
        script.append("$.each(markup.find(\".wrap_radio\"),function() {"
                + "var select = $(this).children(\"input:checked\").attr(\"value\");"
                + "$(this).children(\".hide-span\").html(select);" + "});");
        script.append("$.each(markup.find(\"select\"),function() {"
                + "if($(this).children(\"option:selected\").length == 0) {"
                + "$(this).next(\".hide-span\").eq(0).html($(this).children(\"option\").eq(0).html());" + "}else {"
                + "$(this).next(\".hide-span\").eq(0).html($(this).children(\"option:selected\").html());" + "}"
                + "});");
        script.append("var innerTexts = \"\";");
        script.append("$.each(markup.find(\"#selector .hide-span\"),function() {"
                + "innerTexts += $(this).attr(\"data-name\") + \":\" + $(this).html() + \"  \";" + "});");
        script.append("markup.find(\"#selector\").css(\"text-align\",\"center\").html(innerTexts+\"<br><br>\");");
        script.append("markup.find(\"#box\").css(\"text-align\",\"center\");");
        script.append("markup.find(\"#box .bod\").after(\"<br><br>\");");
        script.append("var inHTML = markup.html();");
        // 模擬表單提交同步方式下載文件
        script.append("var url = 'adminPath/oa/commons/exportWord';");
        script.append("var form = $(\"<form></form>\").attr(\"action\", url).attr(\"method\", \"post\");");
        script.append(
                "form.append($(\"<input></input>\").attr(\"type\", \"hidden\").attr(\"name\", \"html\").attr(\"value\", inHTML));");
        script.append(
                "form.append($(\"<input></input>\").attr(\"type\", \"hidden\").attr(\"name\", \"imgs\").attr(\"value\", JSON.stringify({'echartArr':echartArr})));");
        script.append("form.appendTo('body').submit().remove();");
        script.append("});");
        d.setText(div);
        d.setValue(script.toString());
        return d;
    }

 

模擬form表單傳遞了兩個參數:

html:即你要導出部分的html,看上面代碼我是先clone一個標簽,在對clone的標簽進行了操作。設置布局,你可以直接以行內式的方式設置html樣式,寫入word文檔后行內式樣式依然會被識別,或者你像這篇文章里那樣自己寫html的頭部,並把styles字符串貼進去,word文檔也能識別。
echartArr:這個json對象里存儲了echarts圖的base64碼和圖片的名稱

 前端內容到此結束

 

======================下面是后台處理過程===================

思路:1.創建臨時文件夾 。2.將前台獲取的圖像的base64轉化為真實圖片,放入臨時文件夾。3.在臨時文件夾中創建臨時空白word文檔,將前台獲取的html寫入該空白文檔,並將該空白文檔中特定字符串替換為真實圖片【其實是將圖片的絕對路徑插入word文檔中】。4.創建一個要導出的最終文檔,用代碼的當時執行復制粘貼,將臨時文檔內容粘貼到要導出的文檔。5.導出最終文檔,刪除臨時文件夾。

 控制器:

/**
     * 獲取存有每張圖片datURL的數組,創建圖片,返回臨時文件夾名和每張圖片名
     * 
     * @param imgs
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/exportWord")
    public String exportWord(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String html = request.getParameter("html");
        String imgs = request.getParameter("imgs");

        BufferedInputStream bis = null;
        OutputStream os = null;
        String localpath = request.getSession().getServletContext().getRealPath("static" + File.separator + "images");
        // 生成uuid作為臨時文件夾名稱,防止多並發創建同名img文件
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        localpath = localpath + File.separator + uuid;
        try {
            String docName = getWord(imgs, html, localpath);
            // 寫入瀏覽器
            docName = docName + ".doc";
            File complete = new File(localpath + File.separator + docName);
            response.reset();
            response.setContentType("application/x-download");
            docName = URLEncoder.encode(docName, "utf-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + docName);
            response.addHeader("Content-Length", "" + complete.length());

            bis = new BufferedInputStream(new FileInputStream(complete));
            byte[] b = new byte[bis.available()];
            int i = 0;
            os = response.getOutputStream();
            while ((i = bis.read(b)) != -1) {
                os.write(b, 0, i);
            }
            os.flush();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 清空臨時文件夾
            clearTempFile(localpath);
        }
        return "success";
    }

    /**
     * 創建空白文檔_寫入html_處理空白文檔image_復制空白文檔至最終文檔
     * 
     * @param imgs
     * @param html
     * @param localpath
     */
    public String getWord(String imgs, String html, String localpath) {
        Document document = null;
        createTempFile(localpath);
        // 處理ajax傳來的字符串
        net.sf.json.JSONObject imgsObj = net.sf.json.JSONObject.fromObject(imgs);
        JSONArray imgsJson = imgsObj.getJSONArray("echartArr");
        // 創建圖片,獲取圖片-地址集合
        Map<String, String> imgMap = createImg(localpath, imgsJson);
        // 解析html_創建空白文檔_html寫入空白文檔
        document = Jsoup.parse(html);
        createWord(localpath, "blank");
        File doc = new File(localpath + File.separator + "blank.doc");
        FileWriter fw;
        try {
            fw = new FileWriter(doc);
            fw.write(document.html(), 0, document.html().length());// 寫入文件
            fw.flush(); // 清空FileWriter緩沖區
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String complete = "統計分析系統" + DateUtils.getDate();
        // 復制空白文檔-粘貼到臨時文檔(相當於手動執行copy_paste)
        MSOfficeGeneratorUtils officeUtils = new MSOfficeGeneratorUtils(false);
        officeUtils.openDocument(localpath + File.separator + "blank.doc");
        officeUtils.copy(); // 拷貝整篇文檔
        officeUtils.close();
        officeUtils.createNewDocument();
        officeUtils.paste(); // 粘貼整篇文檔
        // 將圖片${image_name}替換為真實圖片
        for (Entry<String, String> entry : imgMap.entrySet())
            officeUtils.replaceText2Image(entry.getKey(), entry.getValue());
        officeUtils.setFont(true, false, false, "0,0,0", "20", "宋體"); // 設置字體,具體參數
        officeUtils.saveAs(localpath + File.separator + complete + ".doc"); // 生成D:\UUID.doc文件,利用UUID防止同名
        officeUtils.close(); // 關閉Office Word創建的文檔
        officeUtils.quit(); // 退出Office Word程序

        imgMap.clear();
        return complete;
    }

    /**
     * 創建臨時文件夾
     * 
     * @param localpath
     */
    public void createTempFile(String localpath) {
        try {
            File tempFile = new File(localpath);
            if (!tempFile.exists()) {
                tempFile.mkdir();
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    /**
     * 創建word文檔
     * 
     * @param localpath
     * @param name
     * @return
     */
    public void createWord(String localpath, String name) {
        MSOfficeGeneratorUtils msOfficeUtils = new MSOfficeGeneratorUtils(false); // 整合過程設置為可見
        msOfficeUtils.createNewDocument();
        msOfficeUtils.saveAs(localpath + File.separator + name + ".doc");
        msOfficeUtils.close();
        msOfficeUtils.quit();
    }

    /**
     * 將base64轉化為圖片
     * 
     * @param localpath
     * @param imgsJson
     *            圖片在文檔中的鍵${name} - 值圖片的絕對路徑
     * @return
     */
    public Map<String, String> createImg(String localpath, JSONArray imgsJson) {
        Map<String, String> imgMap = new HashMap<String, String>();
        for (Object object : imgsJson) {
            String name = ((net.sf.json.JSONObject) object).getString("name");
            String imgDataURL = ((net.sf.json.JSONObject) object).getString("imgDataURL");
            String imgPath = localpath + File.separator + name;
            String type = CommonUtils.GenerateImage(imgPath, imgDataURL);
            imgMap.put("${" + name + "}", imgPath + "." + type);
        }
        return imgMap;
    }

    /**
     * 刪除臨時文件夾
     * 
     * @param fileName
     * @return
     */
    public boolean clearTempFile(String localpath) {
        boolean flag = true;
        try {
            flag = FileUtils.deleteDirectory(localpath);
        } catch (Exception e) {
            System.out.println(e);
            return flag;
        }
        return flag;
    }

 將base64轉化為圖片:

/**
     * base64字符串轉化成圖片  
     * @param imgStr
     * @return
     */
    public static String GenerateImage(String imgFile,String imgStr) {   //對字節數組字符串進行Base64解碼並生成圖片  
        String type = "png";
        if (StringUtils.isBlank(imgStr)) //圖像數據為空  
            return "false";  
        BASE64Decoder decoder = new BASE64Decoder();  
        try   
        {      
            //獲取圖片類型
            String[] splitData = imgStr.split(";base64,");
            if(splitData.length == 1) {
                imgStr = splitData[0];
            }else {
                type = splitData[0].split("/")[1];
                imgStr = splitData[1];
            }
            //Base64解碼  
            byte[] b = decoder.decodeBuffer(imgStr);  
            for(int i=0;i<b.length;++i)  
            {  
                if(b[i]<0)  
                {//調整異常數據  
                    b[i]+=256;  
                }  
            }  
            //生成jpeg圖片  
            String imgFilePath = imgFile + "." +type;//新生成的圖片  
            OutputStream out = new FileOutputStream(imgFilePath);      
            out.write(b);  
            out.flush();  
            out.close();  
            return type;  
        }   
        catch (Exception e)   
        {  
            return "false";  
        }  
    }  

 用到的工具類:MSOfficeGeneratorUtils.java

package com.echarts.config.page.utils;

import java.util.List;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class MSOfficeGeneratorUtils {
    /**
     * * Microsoft Office Word 程序對象
     */
    private ActiveXComponent word = null;

    /**
     * Word 活動文檔對象
     */
    private Dispatch document = null;

    /**
     * 所有 Word 文檔對象
     */
    private Dispatch documents = null;

    /**
     * *selection 代表當前活動文檔窗口中的所選內容。如果文檔中沒有選中任何內容,則此對象代表插入點(即光標所在位置)。<br/>
     * * 每個文檔窗口中只能存在一個selection對象,並且在整個應用程序中,只能存在一個活動的selection對象
     */
    private Dispatch selection = null;

    /**
     * * range 對象代表文檔中的一個連續的區域。每個range對象由一個起始字符位置與結束字符位置定義。<br/>
     * * range 對象獨立於所選內容。你可以定義和處理一個范圍而無需改變所選內容。還可以在文檔中定義多個范圍。但每個文檔中只能有一個所選內容
     */
    private Dispatch range = null;

    /**
     * * PageSetup 對象包含文檔所有頁面的設置屬性(如紙張大小,左邊距,下邊距)
     */
    private Dispatch pageSetup = null;

    /**
     * * 文檔中的所有表格對象
     */
    private Dispatch tables = null;

    /** 單個表格對象 */
    private Dispatch table = null;

    /** 表格所有行對象 */
    private Dispatch rows = null;

    /** 表格所有列對象 */
    private Dispatch cols = null;

    /** 表格指定行對象 */
    private Dispatch row = null;

    /** 表格指定列對象 */
    private Dispatch col = null;

    /** 表格中指定的單元格 */
    private Dispatch cell = null;

    /** 字體 */
    private Dispatch font = null;

    /** 對齊方式 */
    private Dispatch alignment = null;

    /**
     * * 構造方法 * * @param visible * 設置在生成word文檔時,程序是否可見
     */
    public MSOfficeGeneratorUtils(boolean visible) {
        if (this.word == null) {
            // 初始化Microsoft Office Word 實例
            this.word = new ActiveXComponent("Word.Application");
            this.word.setProperty("Visible", new Variant(visible));
            // 禁用宏
            this.word.setProperty("AutomationSecurity", new Variant(3));
        }
        if (this.documents == null)
            this.documents = word.getProperty("Documents").toDispatch();
    }

    /**
     * * 設置頁面方向與頁邊距 * * @param orientation * 頁面方向 *
     * <ul>
     * *
     * <li>0 橫向</li> *
     * <li>1 縱向</li> *
     * </ul>
     * * @param leftMargin * 左邊距 * @param rightMargin * 右邊距 * @param topMargin * 上邊距
     * * @param buttomMargin * 下邊距
     */
    public void setPageSetup(int orientation, int leftMargin, int rightMargin, int topMargin, int buttomMargin) {
        if (this.pageSetup == null)
            this.getPageSetup();
        Dispatch.put(pageSetup, "Orientation", orientation);
        Dispatch.put(pageSetup, "LeftMargin", leftMargin);
        Dispatch.put(pageSetup, "RightMargin", rightMargin);
        Dispatch.put(pageSetup, "TopMargin", topMargin);
        Dispatch.put(pageSetup, "BottomMargin", buttomMargin);
    }

    /**
     * * 打開word文檔 * * @param docPath * word文檔路徑 * @return 打開的文檔對象
     */
    public Dispatch openDocument(String docPath) {
        this.document = Dispatch.call(documents, "Open", docPath).toDispatch();
        this.getSelection();
        this.getRange();
        this.getAlignment();
        this.getFont();
        this.getPageSetup();
        return this.document;
    }

    /**
     * * 創建一篇新文檔 * * @return 文檔對象
     */
    public Dispatch createNewDocument() {
        this.document = Dispatch.call(documents, "Add").toDispatch();
        this.getSelection();
        this.getRange();
        this.getPageSetup();
        this.getAlignment();
        this.getFont();
        return this.document;
    }

    /**
     * * 獲取選定的內容或插入點 * * @return selection
     */
    public Dispatch getSelection() {
        this.selection = word.getProperty("Selection").toDispatch();
        return this.selection;
    }

    /**
     * * 獲取當前文檔中可以修改的部分,前提是必須存在選中內容 * * @return range
     */
    public Dispatch getRange() {
        this.range = Dispatch.get(this.selection, "Range").toDispatch();
        return this.range;
    }

    /**
     * * 獲得當前文檔的頁面屬性
     */
    public Dispatch getPageSetup() {
        if (this.document == null)
            return this.pageSetup;
        this.pageSetup = Dispatch.get(this.document, "PageSetup").toDispatch();
        return this.pageSetup;
    }

    /**
     * * 把選中內容或插入點向上移動 * * @param count * 移動的距離
     */
    public void moveUp(int count) {
        for (int i = 0; i < count; i++)
            Dispatch.call(this.selection, "MoveUp");
    }

    /**
     * * 把選中內容或插入點向下移動 * * @param count * 移動的距離
     */
    public void moveDown(int count) {
        for (int i = 0; i < count; i++)
            Dispatch.call(this.selection, "MoveDown");
    }

    /**
     * * 把選中內容或插入點向左移動 * * @param count * 移動的距離
     */
    public void moveLeft(int count) {
        for (int i = 0; i < count; i++)
            Dispatch.call(this.selection, "MoveLeft");
    }

    /**
     * * 把選中內容或插入點向右移動 * * @param count * 移動的距離
     */
    public void moveRight(int count) {
        for (int i = 0; i < count; i++)
            Dispatch.call(this.selection, "MoveRight");
    }

    /**
     * * 執行硬換行(回車鍵) * * @param count * 換行數
     */
    public void enterDown(int count) {
        for (int i = 0; i < count; i++)
            Dispatch.call(this.selection, "TypeParagraph");
    }

    /**
     * * 把插入點移動到文件首位置
     */
    public void moveStart() {
        Dispatch.call(this.selection, "HomeKey", new Variant(6));
    }

    /**
     * * 把插入點移動到文件末尾
     */
    public void moveEnd() {
        Dispatch.call(selection, "EndKey", new Variant(6));
    }

    /**
     * * 從選定內容或插入點開始查找文本 * * @param toFindText * 要查找的內容 * @return 查詢到的內容並選中
     */
    public boolean find(String toFindText) {
        // 從selection所在位置開始查詢
        Dispatch find = Dispatch.call(this.selection, "Find").toDispatch();
        // 設置要查找的?熱?br />
        Dispatch.put(find, "Text", toFindText);
        // 向前查找
        Dispatch.put(find, "Forward", "True");
        // 設置格式
        Dispatch.put(find, "Format", "True");
        // 大小寫匹配
        Dispatch.put(find, "MatchCase", "True");
        // 全字匹配
        Dispatch.put(find, "MatchWholeWord", "True");
        // 查找並選中
        return Dispatch.call(find, "Execute").getBoolean();
    }

    /**
     * * 替換選定的內容 * * @param newText * 要替換的內容
     */
    public void replace(String newText) {
        // 設置替換文本
        Dispatch.put(this.selection, "Text", newText);
    }

    /**
     * * 全局替換 * * @param oldText * 要替換的內容 * @param replaceObj * 被替換的內容
     */
    public void replaceAll(String oldText, Object replaceObj) {
        // 將插入點移到文件開頭
        moveStart();
        // 表格替換方式
        String newText = (String) replaceObj;
        // 圖片替換方式
        if (oldText.indexOf("image") != -1 || newText.lastIndexOf(".bmp") != -1 || newText.lastIndexOf(".jpg") != -1
                || newText.lastIndexOf(".gif") != -1) {
            while (find(oldText)) {
                insertImage(newText);
                Dispatch.call(this.selection, "MoveRight");
            }
            // 文本方式
        } else {
            while (find(oldText)) {
                replace(newText);
                Dispatch.call(this.selection, "MoveRight");
            }
        }
    }

    /**
     * * 將指定的內容替換成圖片 * @param replaceText 指定的內容 * @param imgPath 圖片路徑
     */
    public void replaceText2Image(String replaceText, String imgPath) {
        moveStart();
        while (find(replaceText)) {
            insertImage(imgPath);
            moveEnd();
            enterDown(1);
        }
    }

    /**
     * * 向當前插入點替換圖片 * * @param imagePath * 圖片的路徑
     */
    public void insertImage(String imagePath) {
        Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(), "AddPicture", imagePath);
    }

    /**
     * * 合並單元格 * * @param tableIndex * 表格下標,從1開始 * @param fstCellRowIdx * 開始行
     * * @param fstCellColIdx * 開始列 * @param secCellRowIdx * 結束行 * @param
     * secCellColIdx * 結束列
     */
    public void mergeCell(int tableIndex, int fstCellRowIdx, int fstCellColIdx, int secCellRowIdx, int secCellColIdx) {
        getTable(tableIndex);
        Dispatch fstCell = Dispatch.call(table, "Cell", new Variant(fstCellRowIdx), new Variant(fstCellColIdx))
                .toDispatch();
        Dispatch secCell = Dispatch.call(table, "Cell", new Variant(secCellRowIdx), new Variant(secCellColIdx))
                .toDispatch();
        Dispatch.call(fstCell, "Merge", secCell);
    }

    /**
     * * 拆分當前單元格 * * @param numRows * 拆分的行數,如果不想拆分行,請指定為1 * @param numColumns *
     * 拆分的列數,如果不想拆分列,請指定為1
     */
    public void splitCell(int numRows, int numColumns) {
        Dispatch.call(this.cell, "Split", new Variant(numRows), new Variant(numColumns));
    }

    /**
     * * 向表格中寫入內容 * * @param list * 要寫入的內容<br/>
     * * 注:list.size() 應該與表格的rows一致,String數組的length屬性應與表格的columns一致
     */
    public void insertToTable(List<String[]> list) {
        if (list == null || list.size() <= 0)
            return;
        if (this.table == null)
            return;
        for (int i = 0; i < list.size(); i++) {
            String[] strs = list.get(i);
            for (int j = 0; j < strs.length; j++) {
                // 遍歷表格中每一??單元格,遍歷次數所要填入的?熱菔?肯嗤?br /> Dispatch cell = this.getCell(i + 1, j
                // + 1);
                // 選中此單元格
                Dispatch.call(cell, "Select");
                // 寫入?熱蕕醬說ピ?裰?br /> Dispatch.put(this.selection, "Text", strs[j]);
                // 將插入點移動至下一??位置
            }
            this.moveDown(1);
        }
        // 換行
        this.enterDown(1);
    }

    /**
     * * 向當前插入點插入文本內容 * * @param list * 要插入的內容,list.size()代表行數
     */
    public void insertToDocument(List<String> list) {
        if (list == null || list.size() <= 0)
            return;
        if (this.document == null)
            return;
        for (String str : list) {
            Dispatch.put(this.selection, "Text", str);
            this.moveDown(1);
            this.enterDown(1);
        }
    }

    /**
     * * 在當前插入點插入文本 * * @param insertText * 要插入的文本
     */
    public void insertToText(String insertText) {
        Dispatch.put(this.selection, "Text", insertText);
    }

    /**
     * *
     * 在當前插入點插入字符串,利用此方法插入一行text后,Word會默認選中它,如果再調用此方法,會將原來的內容覆蓋掉,所以調用此方法后,記得調用moveRight,將偏移量向右邊移動一個位置
     * 。 * @param newText 要插入的新字符串
     */
    public void insertText(String newText) {
        Dispatch.put(selection, "Text", newText);
    }

    /**
     * * 創建新的表格 * * @param rowCount * 行 * @param colCount * 列 * @param width * 表格邊框
     * *
     * <ul>
     * *
     * <li>0 無邊框</li> *
     * <li>1 有邊框</li> *
     * </ul>
     * * @return 表格對象
     */
    public Dispatch createNewTable(int rowCount, int colCount, int width) {
        if (this.tables == null)
            this.getTables();
        this.getRange();
        if (rowCount > 0 && colCount > 0)
            this.table = Dispatch.call(this.tables, "Add", this.range, new Variant(rowCount), new Variant(colCount),
                    new Variant(width)).toDispatch();
        return this.table;
    }

    /**
     * * 獲取當前document對象中的所有表格對象 * * @return tables
     */
    public Dispatch getTables() {
        if (this.document == null)
            return this.tables;
        this.tables = Dispatch.get(this.document, "Tables").toDispatch();
        return this.tables;
    }

    /**
     * * 獲取當前文檔中的所有表格數量 * * @return 表格數量
     */
    public int getTablesCount() {
        if (this.tables == null)
            this.getTables();
        return Dispatch.get(tables, "Count").getInt();
    }

    /**
     * * 根據索引獲得table對象 * * @param tableIndex * 索引 * @return table
     */
    public Dispatch getTable(int tableIndex) {
        if (this.tables == null)
            this.getTables();
        if (tableIndex >= 0)
            this.table = Dispatch.call(this.tables, "Item", new Variant(tableIndex)).toDispatch();
        return this.table;
    }

    /**
     * * 在指定的單元格里填寫數據 * * @param tableIndex * 表格索引 * @param cellRowIdx * 行索引
     * * @param cellColIdx * 列索引 * @param txt * 文本
     */
    public void putTxtToCell(int tableIndex, int cellRowIdx, int cellColIdx, String txt) {
        getTable(tableIndex);
        getCell(cellRowIdx, cellColIdx);
        Dispatch.call(this.cell, "Select");
        Dispatch.put(this.selection, "Text", txt);
    }

    /**
     * * 在當前文檔末尾拷貝來自另一個文檔中的段落 * * @param anotherDocPath * 另一個文檔的磁盤路徑 * @param
     * tableIndex * 被拷貝的段落在另一格文檔中的序號(從1開始)
     */
    public void copyParagraphFromAnotherDoc(String anotherDocPath, int paragraphIndex) {
        Dispatch wordContent = Dispatch.get(this.document, "Content").toDispatch(); // 取得當前文檔的內容
        Dispatch.call(wordContent, "InsertAfter", "$selection$");// 插入特殊符定位插入點
        copyParagraphFromAnotherDoc(anotherDocPath, paragraphIndex, "$selection$");
    }

    /**
     * * 在當前文檔指定的位置拷貝來自另一個文檔中的段落 * * @param anotherDocPath * 另一個文檔的磁盤路徑 * @param
     * tableIndex * 被拷貝的段落在另一格文檔中的序號(從1開始) * @param pos * 當前文檔指定的位置
     */
    public void copyParagraphFromAnotherDoc(String anotherDocPath, int paragraphIndex, String pos) {
        Dispatch doc2 = null;
        try {
            doc2 = Dispatch.call(documents, "Open", anotherDocPath).toDispatch();
            Dispatch paragraphs = Dispatch.get(doc2, "Paragraphs").toDispatch();
            Dispatch paragraph = Dispatch.call(paragraphs, "Item", new Variant(paragraphIndex)).toDispatch();
            Dispatch range = Dispatch.get(paragraph, "Range").toDispatch();
            Dispatch.call(range, "Copy");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (doc2 != null) {
                Dispatch.call(doc2, "Close", new Variant(true));
                doc2 = null;
            }
        }

    }

    /**
     * * 在當前文檔指定的位置拷貝來自另一個文檔中的表格 * * @param anotherDocPath * 另一個文檔的磁盤路徑 * @param
     * tableIndex * 被拷貝的表格在另一格文檔中的序號(從1開始) * @param pos * 當前文檔指定的位置
     */
    public void copyTableFromAnotherDoc(String anotherDocPath, int tableIndex, String pos) {
        Dispatch doc2 = null;
        try {
            doc2 = Dispatch.call(documents, "Open", anotherDocPath).toDispatch();
            Dispatch tables = Dispatch.get(doc2, "Tables").toDispatch();
            Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex)).toDispatch();
            Dispatch range = Dispatch.get(table, "Range").toDispatch();
            Dispatch.call(range, "Copy");
            if (this.find(pos)) {
                getRange();
                Dispatch.call(this.range, "Paste");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (doc2 != null) {
                Dispatch.call(doc2, "Close", new Variant(true));
                doc2 = null;
            }
        }
    }

    /**
     * * 在當前文檔指定的位置拷貝來自另一個文檔中的圖片 * * @param anotherDocPath * 另一個文檔的磁盤路徑 * @param
     * shapeIndex * 被拷貝的圖片在另一格文檔中的位置 * @param pos * 當前文檔指定的位置
     */
    public void copyImageFromAnotherDoc(String anotherDocPath, int shapeIndex, String pos) {
        Dispatch doc2 = null;
        try {
            doc2 = Dispatch.call(documents, "Open", anotherDocPath).toDispatch();
            Dispatch shapes = Dispatch.get(doc2, "InLineShapes").toDispatch();
            Dispatch shape = Dispatch.call(shapes, "Item", new Variant(shapeIndex)).toDispatch();
            Dispatch imageRange = Dispatch.get(shape, "Range").toDispatch();
            Dispatch.call(imageRange, "Copy");
            if (this.find(pos)) {
                getRange();
                Dispatch.call(this.range, "Paste");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (doc2 != null) {
                Dispatch.call(doc2, "Close", new Variant(true));
                doc2 = null;
            }
        }
    }

    /**
     * * 在指定的表格的指定行前面增加行 * * @param tableIndex * word文件中的第N張表(從1開始) * @param
     * rowIndex * 指定行的序號(從1開始)
     */
    public void addTableRow(int tableIndex, int rowIndex) {
        getTable(tableIndex);
        getTableRows();
        getTableRow(rowIndex);
        Dispatch.call(this.rows, "Add", new Variant(this.row));
    }

    /**
     * * 在第1行前增加一行 * * @param tableIndex * word文檔中的第N張表(從1開始)
     */
    public void addFirstTableRow(int tableIndex) {
        getTable(tableIndex);
        getTableRows();
        Dispatch row = Dispatch.get(rows, "First").toDispatch();
        Dispatch.call(this.rows, "Add", new Variant(row));
    }

    /**
     * 在最后1行前增加一行 * * @param tableIndex * word文檔中的第N張表(從1開始)
     */
    public void addLastTableRow(int tableIndex) {
        getTable(tableIndex);
        getTableRows();
        Dispatch row = Dispatch.get(this.rows, "Last").toDispatch();
        Dispatch.call(this.rows, "Add", new Variant(row));
    }

    /**
     * * 增加一行 * * @param tableIndex * word文檔中的第N張表(從1開始)
     */
    public void addRow(int tableIndex) {
        getTable(tableIndex);
        getTableRows();
        Dispatch.call(this.rows, "Add");
    }

    /**
     * * 增加一列 * * @param tableIndex * word文檔中的第N張表(從1開始)
     */
    public void addCol(int tableIndex) {
        getTable(tableIndex);
        getTableColumns();
        Dispatch.call(this.cols, "Add").toDispatch();
        Dispatch.call(this.cols, "AutoFit");
    }

    /**
     * * 在指定列前面增加表格的列 * * @param tableIndex * word文檔中的第N張表(從1開始) * @param colIndex *
     * 指定列的序號 (從1開始)
     */
    public void addTableCol(int tableIndex, int colIndex) {
        getTable(tableIndex);
        getTableColumns();
        getTableColumn(colIndex);
        Dispatch.call(this.cols, "Add", this.col).toDispatch();
        Dispatch.call(this.cols, "AutoFit");
    }

    /**
     * * 在第1列前增加一列 * * @param tableIndex * word文檔中的第N張表(從1開始)
     */
    public void addFirstTableCol(int tableIndex) {
        getTable(tableIndex);
        Dispatch cols = getTableColumns();
        Dispatch col = Dispatch.get(cols, "First").toDispatch();
        Dispatch.call(cols, "Add", col).toDispatch();
        Dispatch.call(cols, "AutoFit");
    }

    /**
     * * 在最后一列前增加一列 * * @param tableIndex * word文檔中的第N張表(從1開始)
     */
    public void addLastTableCol(int tableIndex) {
        getTable(tableIndex);
        Dispatch cols = getTableColumns();
        Dispatch col = Dispatch.get(cols, "Last").toDispatch();
        Dispatch.call(cols, "Add", col).toDispatch();
        Dispatch.call(cols, "AutoFit");
    }

    /**
     * * 獲取當前表格的列數 * * @return 列總數
     */
    public int getTableColumnsCount() {
        if (this.table == null)
            return 0;
        return Dispatch.get(this.cols, "Count").getInt();
    }

    /**
     * * 獲取當前表格的行數 * * @return 行總數
     */
    public int getTableRowsCount() {
        if (this.table == null)
            return 0;
        return Dispatch.get(this.rows, "Count").getInt();
    }

    /**
     * * 獲取當前表格的所有列對象 * * @return cols
     */
    public Dispatch getTableColumns() {
        if (this.table == null)
            return this.cols;
        this.cols = Dispatch.get(this.table, "Columns").toDispatch();
        return this.cols;
    }

    /**
     * * 獲取當前表格的所有行對象 * * @return rows
     */
    public Dispatch getTableRows() {
        if (this.table == null)
            return this.rows;
        this.rows = Dispatch.get(this.table, "Rows").toDispatch();
        return this.rows;
    }

    /**
     * * 根據索引獲得當前表格的列對象 * * @param columnIndex * 列索引 * @return col
     */
    public Dispatch getTableColumn(int columnIndex) {
        if (this.cols == null)
            this.getTableColumns();
        if (columnIndex >= 0)
            this.col = Dispatch.call(this.cols, "Item", new Variant(columnIndex)).toDispatch();
        return this.col;
    }

    /**
     * * 根據索引獲得當前表格的行對象 * * @param rowIndex * 行索引 * @return row
     */
    public Dispatch getTableRow(int rowIndex) {
        if (this.rows == null)
            this.getTableRows();
        if (rowIndex >= 0)
            this.row = Dispatch.call(this.rows, "Item", new Variant(rowIndex)).toDispatch();
        return this.row;
    }

    /**
     * * 自動調整當前所有表格
     */
    public void autoFitTable() {
        int count = this.getTablesCount();
        for (int i = 0; i < count; i++) {
            Dispatch table = Dispatch.call(tables, "Item", new Variant(i + 1)).toDispatch();
            Dispatch cols = Dispatch.get(table, "Columns").toDispatch();
            Dispatch.call(cols, "AutoFit");
        }
    }

    /**
     * * 根據行索引與列索引獲取當前表格中的單元格 * * @param cellRowIdx * 行索引 * @param cellColIdx * 列索引
     * * @return cell對象
     */
    public Dispatch getCell(int cellRowIdx, int cellColIdx) {
        if (this.table == null)
            return this.cell;
        if (cellRowIdx >= 0 && cellColIdx >= 0)
            this.cell = Dispatch.call(this.table, "Cell", new Variant(cellRowIdx), new Variant(cellColIdx))
                    .toDispatch();
        return this.cell;
    }

    public void selectCell(int cellRowIdx, int cellColIdx) {
        if (this.table == null)
            return;
        getCell(cellRowIdx, cellColIdx);
        if (cellRowIdx >= 0 && cellColIdx >= 0)
            Dispatch.call(this.cell, "select");
    }

    /**
     * * 設置當前文檔的標題 * * @param title 標題 * @param alignmentType 對齊方式 * @see
     * setAlignment
     */
    public void setTitle(String title, int alignmentType) {
        if (title == null || "".equals(title))
            return;
        if (this.alignment == null)
            this.getAlignment();
        if (alignmentType != 0 && alignmentType != 1 && alignmentType != 2)
            alignmentType = 0;
        Dispatch.put(this.alignment, "Alignment", alignmentType);
        Dispatch.call(this.selection, "TypeText", title);
    }

    /**
     * * 設置當前表格邊框的粗細 * * @param width * 范圍:1 < w < 13, 如果是0,就代表?]有框<br/>
     * 
     */
    public void setTableBorderWidth(int width) {
        if (this.table == null)
            return;
        /*
         * 設置表格線的粗細 1:代表最上邊一條線 2:代表最左邊一條線 3:最下邊一條線 4:最右邊一條線 5:除最上邊最下邊之外的所有橫線
         * 6:除最左邊最右邊之外的所有豎線 7:從左上角到右下角的斜線 8:從左下角到右上角的斜線
         */
        Dispatch borders = Dispatch.get(table, "Borders").toDispatch();
        Dispatch border = null;
        for (int i = 1; i < 7; i++) {
            border = Dispatch.call(borders, "Item", new Variant(i)).toDispatch();
            if (width != 0) {
                Dispatch.put(border, "LineWidth", new Variant(width));
                Dispatch.put(border, "Visible", new Variant(true));
            } else if (width == 0) {
                Dispatch.put(border, "Visible", new Variant(false));
            }
        }
    }

    /**
     * * 得到指定的表格指定的單元格中的值 * * @param tableIndex * 表格索引(從1開始) * @param rowIndex *
     * 行索引(從1開始) * @param colIndex * 列索引(從1開始) * @return
     */
    public String getTxtFromCell(int tableIndex, int rowIndex, int colIndex) {
        String value = "";
        // 設置為當前表格
        getTable(tableIndex);
        getCell(rowIndex, colIndex);
        if (cell != null) {
            Dispatch.call(cell, "Select");
            value = Dispatch.get(selection, "Text").toString();
            value = value.substring(0, value.length() - 2); // 去掉最后的回車符;
        }
        return value;
    }

    /**
     * * 對當前選中的內容設置項目符號與列表 * * @param tabIndex *
     * <ul>
     * *
     * <li>1.項目編號</li> *
     * <li>2.編號</li> *
     * <li>3.多級編號</li> *
     * <li>4.列表樣式</li> *
     * </ul>
     * * @param index * 0表示沒有,其它數字代表是該tab頁中的第幾項內容
     */
    public void applyListTemplate(int tabIndex, int index) {
        // 取得ListGalleries對象列表
        Dispatch listGalleries = Dispatch.get(this.word, "ListGalleries").toDispatch();
        // 取得列表中一個對象
        Dispatch listGallery = Dispatch.call(listGalleries, "Item", new Variant(tabIndex)).toDispatch();
        Dispatch listTemplates = Dispatch.get(listGallery, "ListTemplates").toDispatch();
        if (this.range == null)
            this.getRange();
        Dispatch listFormat = Dispatch.get(this.range, "ListFormat").toDispatch();
        Dispatch.call(listFormat, "ApplyListTemplate", Dispatch.call(listTemplates, "Item", new Variant(index)),
                new Variant(true), new Variant(1), new Variant(0));
    }

    /**
     * * 增加文檔目錄
     */
    public void addTablesOfContents() {
        // 取得ActiveDocument、TablesOfContents、range對象
        Dispatch ActiveDocument = word.getProperty("ActiveDocument").toDispatch();
        Dispatch TablesOfContents = Dispatch.get(ActiveDocument, "TablesOfContents").toDispatch();
        Dispatch range = Dispatch.get(this.selection, "Range").toDispatch();
        // 增加目錄
        Dispatch.call(TablesOfContents, "Add", range, new Variant(true), new Variant(1), new Variant(3),
                new Variant(true), new Variant(""), new Variant(true), new Variant(true));
    }

    /**
     * * 設置當前selection對齊方式 * * @param alignmentType *
     * <ul>
     * *
     * <li>0.居左</li> *
     * <li>1.居中</li> *
     * <li>2.居右</li> *
     * </ul>
     * 
     */
    public void setAlignment(int alignmentType) {
        if (this.alignment == null)
            this.getAlignment();
        Dispatch.put(this.alignment, "Alignment", alignmentType);
    }

    /**
     * * 獲取當前selection的對齊方式 * * @return alignment
     */
    public Dispatch getAlignment() {
        if (this.selection == null)
            this.getSelection();
        this.alignment = Dispatch.get(this.selection, "ParagraphFormat").toDispatch();
        return this.alignment;
    }

    /**
     * * 獲取字體對象 * * @return font
     */
    public Dispatch getFont() {
        if (this.selection == null)
            this.getSelection();
        this.font = Dispatch.get(this.selection, "Font").toDispatch();
        return this.font;
    }

    /**
     * * 設置當前selection的字體 * * @param fontName * 字體名稱,如“微軟雅黑” * @param isBold * 是否粗體
     * * @param isItalic * 是否斜體 * @param isUnderline * 是否下划線 * @param rgbColor *
     * 顏色值"1,1,1,1" * @param Scale * 字體間距 * @param fontSize * 字體大小
     */
    @Deprecated
    public void setFontScale(String fontName, boolean isBold, boolean isItalic, boolean isUnderline, String rgbColor,
            int Scale, int fontSize) {
        Dispatch.put(this.font, "Name", fontName);
        Dispatch.put(this.font, "Bold", isBold);
        Dispatch.put(this.font, "Italic", isItalic);
        Dispatch.put(this.font, "Underline", isUnderline);
        Dispatch.put(this.font, "Color", rgbColor);
        Dispatch.put(this.font, "Scaling", Scale);
        Dispatch.put(this.font, "Size", fontSize);
    }

    /**
     * 設置當前選定內容的字體
     * 
     * @param isBold
     *            是否為粗體
     * @param isItalic
     *            是否為斜體
     * @param isUnderLine
     *            是否帶下划線
     * @param color
     *            rgb 字體顏色 例如:紅色 255,0,0
     * @param size
     *            字體大小 12:小四 16:三號
     * @param name
     *            字體名稱 例如:宋體,新宋體,楷體,隸書
     */

    public void setFont(boolean isBold, boolean isItalic, boolean isUnderLine, String color, String size, String name) {
        Dispatch font = Dispatch.get(getSelection(), "Font").toDispatch();
        Dispatch.put(font, "Name", new Variant(name));
        Dispatch.put(font, "Bold", new Variant(isBold));
        Dispatch.put(font, "Italic", new Variant(isItalic));
        Dispatch.put(font, "Underline", new Variant(isUnderLine));
        if (!"".equals(color))
            Dispatch.put(font, "Color", color);
        Dispatch.put(font, "Size", size);
    }

    /**
     * * 保存文件 * * @param outputPath * 保存路徑
     */
    public void saveAs(String outputPath) {
        if (this.document == null)
            return;
        if (outputPath == null || "".equals(outputPath))
            return;
        Dispatch.call(this.document, "SaveAs", outputPath);
    }

    /**
     * * 另存為HTML內容 * * @param htmlFile * html文件路徑
     */
    public void saveAsHtml(String htmlFile) {
        Dispatch.invoke(this.document, "SaveAs", Dispatch.Method, new Object[] { htmlFile, new Variant(8) },
                new int[1]);
    }

    /**
     * * saveFormat | Member name Description 0 | wdFormatDocument Microsoft Word *
     * format. 1 | wdFormatTemplate Microsoft Word template format. 2 | *
     * wdFormatText Microsoft Windows text format. 3 | wdFormatTextLineBreaks *
     * Microsoft Windows text format with line breaks preserved. 4 | *
     * wdFormatDOSText Microsoft DOS text format. 5 | wdFormatDOSTextLineBreaks *
     * Microsoft DOS text with line breaks preserved. 6 | wdFormatRTF Rich text *
     * format (RTF). 7 | wdFormatEncodedText Encoded text format. 7 | *
     * wdFormatUnicodeText Unicode text format. 8 | wdFormatHTML Standard HTML *
     * format. 9 | wdFormatWebArchive Web archive format. 10 | *
     * wdFormatFilteredHTML Filtered HTML format. 11 | wdFormatXML Extensible *
     * Markup Language (XML) format.
     */

    /**
     * * 關閉當前word文檔
     */

    public void close() {
        if (document == null)
            return;
        Dispatch.call(document, "Close", new Variant(0));
    }

    /**
     * * 執行當前文檔打印命令
     */
    public void printFile() {
        if (document == null)
            return;
        Dispatch.call(document, "PrintOut");
    }

    /**
     * * 退出Microsoft Office Word程序
     */
    public void quit() {
        word.invoke("Quit", new Variant[0]);
        ComThread.Release();
    }

    /**
     * * 選中整篇文檔
     */
    public void selectAllContent() {
        Dispatch.call(this.document, "select");
    }

    /**
     * * 復制整篇文檔 * @param target
     */
    public void copy() {
        Dispatch.call(this.document, "select");
        Dispatch.call(this.selection, "copy");
    }

    /**
     * * 在當前插入點位置粘貼選中的內容
     */
    public void paste() {
        Dispatch.call(this.selection, "paste");
    }

}

效果:

頁面:

導出到word:

 存在的問題:導出效率有點低,從點擊導出-瀏覽器導出word耗時5-8s時間。暫且記錄。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM