JavaScript打印Excel、Word

JavaScript調用本地打印機,打印Excel、Word文件


之前寫過一篇文章,使用java調用打印機打印Excel文件:
java調用打印機:http://blog.csdn.net/wangxiaoan1234/article/details/76032280
但是java運行與服務器上,外部訪問無法調用本地打印機。
假設項目需求爲:點擊按鈕打印某個報表(Excel)。當項目發佈到服務器上後,當使用java調用打印機,無論哪臺電腦訪問頁面,點擊打印按鈕,調用的都是java所運行的服務器上的打印機。

理想:

Created with Raphaël 2.1.0用戶用戶服務器服務器我要打印報表收到請求,調用打印程序弄好了,你打印吧調用打印機,打印報表

實際:

Created with Raphaël 2.1.0用戶用戶服務器服務器我要打印報表收到請求,調用打印程序怎麼調用了我自己的打印機,是java的鍋,我不背很抱歉,報表在我這打印好了,你過來取吧!你大爺的!

解決思路:
JavaScript運行在本地,使用JavaScript調用本地打印機。

想到可行方法:

  • 直接調用打印機打印本地文件(IE瀏覽器用此方法)。
  • java後臺將Excel轉換成html頁面,調用window.print()函數打印整個頁面(通用);
  • 安裝打印插件(麻煩)

使用Spring poi將Excel、Word轉換爲html再進行打印的好處有:

  1. 所有瀏覽器通用
  2. 可以進行打印預覽
  3. 可視化的打印參數設置
  4. 我不會別的o(╯□╰)o

IE瀏覽器直接調用打印機(無預覽):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>打印測試</title>
</head>
<body>
    <input id="btnPrint" value="打印整個頁面" type="button" onclick="btnPrintClick()"/>  
    <input id="btnPrintExcel" value="打印Excel" type="button" onclick="printExcel('D:/test.xlsx')"/> 
    <script>
        //調用瀏覽器的打印功能    
        function btnPrintClick(){  
            window.print();  
        }  
        //打印Excel
        function  printExcel(obj) {  
            var explorer = window.navigator.userAgent ;
            if (explorer.indexOf("MSIE") >= 0 || "ActiveXObject" in window) { //判斷是否爲ie瀏覽器
                var xlsApp = null;      
                try {          
                    xlsApp = new ActiveXObject('Excel.Application');    
                } catch(e) {   
                    alert(e + ', 原因分析: 瀏覽器安全級別較高導致不能創建Excel對象或者客戶端沒有安裝Excel軟件');   
                    return;   
                }      
                var xlBook = xlsApp.Workbooks.Open(obj);  
                var xlsheet = xlBook.Worksheets(1);  
                xlsApp.Application.Visible = false;   
                xlsApp.visible = false;   
                xlsheet.Printout;   
                xlsApp.Quit();   
                xlsApp=null;   
            } else {
                alert("只支持IE瀏覽器");
            }
        }  
    </script>
</body>
</html>

Java將Excel解析成html,在該頁面上調用window.print()打印頁面:

maven依賴:

<!-- POI -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.16</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.16</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.lucee/curvesapi -->
        <dependency>
            <groupId>org.lucee</groupId>
            <artifactId>curvesapi</artifactId>
            <version>1.04.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans -->
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>2.6.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.16</version>
        </dependency>

jar包下載地址:http://download.csdn.net/detail/wangxiaoan1234/9909138

後臺Excel轉換HTML類:
類文件下載地址:http://download.csdn.net/detail/wangxiaoan1234/9909123

package com.srie.util.excel;

import org.apache.poi.hssf.converter.ExcelToHtmlConverter;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;

/**
 * 利用POI將Excel2003轉換爲HTML(不能讀取圖片並且不支持Excel2007)
 */
public class PoiExcel03lToHtml {

    /**
     * 程序入口方法
     * @param excelPath 待讀取的Excel路徑
     * @param htmlPath 轉換生成的HTML輸出路徑
     */
    public static void convertExcelToHtml(String excelPath, String htmlPath) {
        File excelFile = new File(excelPath);
        File htmlFile = new File(htmlPath);
        File htmlFolder = htmlFile.getParentFile();
        InputStream is = null;
        OutputStream out = null;
        StringWriter writer = null;
        String content = null;
        try{
            if(excelFile.exists()){
                if(!htmlFolder.exists()){
                    htmlFolder.mkdirs();
                }
                is = new FileInputStream(excelFile);
                HSSFWorkbook workBook = new HSSFWorkbook(is);
                ExcelToHtmlConverter converter = new ExcelToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
                //設置不輸出行號(1 2 3...)及列標(A B C...)等
                converter.setOutputColumnHeaders(false);
                converter.setOutputHiddenColumns(false);
                converter.setOutputColumnHeaders(false);
                converter.setOutputLeadingSpacesAsNonBreaking(false);
                converter.setOutputRowNumbers(false);
                converter.processWorkbook(workBook);

                writer = new StringWriter();
                Transformer serializer = TransformerFactory.newInstance().newTransformer();
                serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
                serializer.setOutputProperty(OutputKeys.INDENT, "YES");
                serializer.setOutputProperty(OutputKeys.METHOD, "HTML");
                serializer.transform(
                        new DOMSource(converter.getDocument()),
                        new StreamResult(writer) );
                out = new FileOutputStream(htmlFile);
                content = writer.toString();
                //替換掉Sheet1 Sheet2 Sheet3...
                content = content.replaceAll("<h2>Sheet[\\d]</h2>", "")
                        .replaceAll("<h2>第[一二三四五六七八九十壹貳叄肆伍陸柒捌玖拾]頁</h2>", "");

                out.write(content.getBytes("UTF-8"));
                out.flush();
                out.close();
                writer.close();
            }
        } catch (IOException | ParserConfigurationException | TransformerException e) {
            e.printStackTrace();
        } finally{
            try{
                if(is != null){
                    is.close();
                }
                if(out != null){
                    out.close();
                }
                if(writer != null){
                    writer.close();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }
}

class TestExcel {
    public static void main(String[] args) throws Exception {
        PoiExcel03lToHtml.convertExcelToHtml("D:/test.xls", "D:/test.html");
    }
}

生成html後就可以各種調用打印了。
我採用的方法是:

  1. 前臺ajax訪問後臺轉換方法
  2. 後臺返回第58行的content字符串,這個字符串就是整個html頁面代碼。
  3. 將ajax的返回結果寫入到一個新頁面,然後打印這個新頁面。

前臺js代碼:

/**
 * 打印方法
 * @author 王曉安
 * @創建時間 2017年7月19日10:32:39
 * @param url 請求打印的路徑
 */
function print(url){
    $.ajax({
        url: url,
        data: {
            ...
        },
        type: "POST",
        dataType: "json",
        success: function(result){
            var printWin=window.open("打印窗口", "_blank");
            printWin.document.write(result);
            printWin.document.close();
            printWin.print();
            printWin.close();
        }
    });
}

測試結果:

Excel文件:
這裏寫圖片描述


生成的html頁面:
生成的html頁面


js打印設置:
這裏寫圖片描述


打印的pdf文件:
這裏寫圖片描述

注意:

當圖表比較寬,所選紙張會出現只打印部分頁面情況。如下所示:
這裏寫圖片描述

解決辦法:
調整頁邊距:效果較小
更換打印紙張:效果明顯
調整縮放:效果明顯

以下圖片是進行縮放的演示:
這裏寫圖片描述


打印word與打印Excel類似:

後臺word2003轉HTML類:
類文件下載地址:http://download.csdn.net/detail/wangxiaoan1234/9909154

package com.srie.util.excel;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.Picture;
import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.List;

/**
 * 利用POI將Excel2003轉換爲HTML(支持圖片但不支持Excel2007)
 */
public class PoiWord03ToHtml {

    /**
     * 程序入口方法
     * @param wordPath 待讀取的word路徑
     * @param htmlPath 轉換生成的HTML輸出路徑
     */
    public static void convertExcelToHtml(String wordPath, String htmlPath){
        File htmlFile = new File(htmlPath);
        File htmlFolder = htmlFile.getParentFile();
        InputStream is = null;
        OutputStream out = null;
        StringWriter writer = null;
        String content;
        try {
            is = new FileInputStream(wordPath);
            HWPFDocument wordDocument = new HWPFDocument(is);
            WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
                    DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
            //不支持λ表達式請用註釋裏面的代碼
            wordToHtmlConverter.setPicturesManager((bytes, pt, string, f, f1) -> string);
           /* wordToHtmlConverter.setPicturesManager(new PicturesManager() {
                public String savePicture(byte[] content, PictureType pictureType,
                                          String suggestedName, float widthInches, float heightInches) {
                    return suggestedName;
                }
            });*/
            wordToHtmlConverter.processDocument(wordDocument);
            List pics = wordDocument.getPicturesTable().getAllPictures();
            if (pics != null) {
                for (Object pic1 : pics) {
                    Picture pic = (Picture) pic1;
                    try {
                        pic.writeImageContent(new FileOutputStream(htmlFolder + pic.suggestFullFileName()));
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
            Document htmlDocument = wordToHtmlConverter.getDocument();

            writer = new StringWriter();
            Transformer serializer = TransformerFactory.newInstance().newTransformer();
            serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            serializer.setOutputProperty(OutputKeys.INDENT, "YES");
            serializer.setOutputProperty(OutputKeys.METHOD, "HTML");
            serializer.transform(new DOMSource(htmlDocument), new StreamResult(writer));
            out = new FileOutputStream(htmlFile);
            content = writer.toString();
            out.write(content.getBytes("UTF-8"));
            out.flush();
            out.close();
            writer.close();
        } catch (IOException | ParserConfigurationException | TransformerException e) {
            e.printStackTrace();
        } finally {
            try{
                if(is != null){
                    is.close();
                }
                if(out != null){
                    out.close();
                }
                if(writer != null){
                    writer.close();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }
}

class TestWord {
    public static void main(String[] args) throws Exception {
        PoiWord03ToHtml.convertExcelToHtml("D:/test.doc", "D:/test.html");
    }
}

測試結果:

word2003文檔:
word2003文檔:

HTML顯示:
html顯示

有哪位大神知道怎麼使用poi將office2007轉換成html嗎?請賜教啊!!!

Exception in thread "main" org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)

同樣的方法,打印.xlsx或者.docx文件時就會拋如上異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章