1. 程式人生 > >前端方法 匯出excel和呼叫瀏覽器列印功能

前端方法 匯出excel和呼叫瀏覽器列印功能

瀏覽的的列印功能目前只有chrome做的最好,會生成a4紙大小的列印預覽,而火狐會將列印預覽變成電腦螢幕的100%;

所以最好用chrome來實現

使用場景:我的頁面是基於table做的,如下圖,需要兩個功能 1.匯出excel 2.直接點選列印按鈕,要求可以呼叫瀏覽器的列印功能。

由於頁面比較複雜,使用java後臺生成表格需要配置的東西過多,比較麻煩,所以我就想到了用html頁面直接生成excel,簡單實用

 點選列印按鈕,生成的列印預覽

 點選匯出excel,生成的excel

 實現方法:

1.html 由於最後要匯出excel,excel對html中的table支援很好,且excel支援大部分的css,所以建議直接將要匯出的頁面用table標籤來寫,下面是我的例子

<html>
<head>

    <%@include file="/common/jsp/meta.jsp" %>
<title>新增錄入</title>

</head>
<body>
<article class="page-container" >
    <div class="col-xs-12 col-sm-12  radius">
        <div class="cl pd-5 bg-1 bk-gray mt-20">
			<span>
			<a href="javascript:;" id="download" class="btn btn-primary radius">
                <i class="Hui-iconfont">&#xe644;</i>匯出EXCEL
            </a>
			</span>
			<span>
			<a href="javascript:;" onclick="printout()" class="btn btn-primary radius">
                <i class="Hui-iconfont">&#xe644;</i>列印
            </a>
			</span>
        </div>
    </div>
    <div id="printContent">
        <style>
            .page-container{
                width:800px;margin:0 auto;
                padding:30px;
            }
            #printContent{
                margin-top:20px;
            }
            table{
                border-collapse: collapse;
                width:100%;
            }
            table td{
                font-size:14px;padding:10px;
            }
            .punishTable tfoot td{
                font-size:16px;font-weight:bold;
            }

            .punishTable td{
                text-align: center;
                border:1px solid #666;align:center;
                font-size:14px;height:60px;
            }
        </style>
        <!--想要沒有頁首頁尾就加這段css-->
        <style media="print">
            @page{
                size:210mm 290 mm;
                margin:0mm auto;
            }
        </style>

        <%--<input type="hidden" value="${assessPunish.ID}" name="ID">--%>
    <div class="row table">
        <table class="headTable">
            <tr>
                <td colspan="6" style="height:70px;font-size:20px;font-weight: bold;text-align: center;">
                ${assessPunish.regionGroupName}考核扣罰表
                </td>
            </tr>
            <tr>
                <td colspan="6" height="50" align="left" style="text-indent: 2em">依照【移集團  合同[${assessPunish.CONTRACT_NO}] 號】《合同名稱》</td>
            </tr>
            <tr>
                <td colspan="6" height="50" align="left">
                    現由地市業務支撐中心對維修公司服務的移動公司營業裝置配件維修工作進行認定,考核扣罰結果如下:
                </td>
            </tr>
            <tr>
                <td colspan="2" align="left" height="60">
                    地市:${assessPunish.regionGroupName}
                </td>
                <td colspan="4" align="left">
                    維修時間段:${assessPunish.REPAIR_DATE}
                </td>
            </tr>
        </table>

        <table class="punishTable">
            <thead>

            </thead>
            <thead>
                <tr>
                    <td>認定大項</td>
                    <td>描述</td>
                    <td>單位</td>
                    <td>數量</td>
                    <td width="60">單價</td>
                    <td width="100">小計</td>
                </tr>
            </thead>
            <tbody id="punishContent">

            </tbody>
            <tfoot>
                <tr>
                    <td colspan="5">
                        合計扣罰(不含增值稅)
                    </td>
                    <td class="sum">${assessPunish.TOTAL}</td>
                </tr>
            </tfoot>
        </table>

        <table class="headTable">
            <tr>
                <td colspan="2" align="left" height="200">
                    業務支撐中心主管簽字:
                </td>
                <td colspan="4" align="left">
                    維修公司主管簽字:
                </td>
            </tr>
            <tr>
                <td colspan="2" align="left" height="200">
                    業務支撐中心經理簽字:
                </td>
                <td colspan="4" align="left">
                    維修公司分管經理簽字:
                </td>
            </tr>
        </table>
    </div>
    </div>
    <div class="row cl text-c">
        <input onClick="removeIframe();" class="btn btn-primary radius ml-10" type="button" value="&nbsp;&nbsp;關閉&nbsp;&nbsp;">
    </div>
</article>

注意:因為列印和匯出表格都是要展示頁面主題內容,而一般頁面上還有導航欄,按鈕啥的,所以要將沒用的元素剔除,只留需要列印的內容 在元素 .printContent中

看下面就知道是將 printContent中的內容重新生成一個html,所以其css需要寫在printContent中,否則新頁面將沒有樣式

另外列印預覽時會自動出現頁首頁尾,不需要的話加一段css就可以解決

<style media="print">
    @page{
        size:210mm 290 mm;
        margin:0mm auto;
    }
</style>

2.呼叫瀏覽器列印介面js

//按列印按鈕呼叫瀏覽器列印介面
function printout() {
   // debugger;
    var newWindow;
    //開啟一個新的視窗
    newWindow = window.open();
    // 是新視窗獲得焦點
    newWindow.focus();
    //儲存寫入內容
    var newContent = "<html><head><meta charset='utf-8'/><title></title></head><body>"
    newContent += document.getElementById("printContent").outerHTML;
    newContent += "</body></html>"
    // 將HTML程式碼寫入新視窗中
    newWindow.document.write(newContent);
    newWindow.print();
    // close layout stream
    newWindow.document.close();
    //關閉開啟的臨時視窗
    newWindow.close();
    return false;
};

 原理就是用window.print()將制定去內容渲染到一個新視窗

3.匯出Excel 的 js

// 使用outerHTML屬性獲取整個table元素的HTML程式碼(包括<table>標籤),然後包裝成一個完整的HTML文件,設定charset為urf-8以防止中文亂碼
var html = "<html><head><meta charset='utf-8' /></head><body>" + document.getElementById("printContent").outerHTML + "</body></html>";
// 例項化一個Blob物件,其建構函式的第一個引數是包含檔案內容的陣列,第二個引數是包含檔案型別屬性的物件
var blob = new Blob([html], {
    type: "application/vnd.ms-excel"
});
var a = document.getElementById("download");
// 利用URL.createObjectURL()方法為a元素生成blob URL
a.href = URL.createObjectURL(blob);
// 設定檔名,目前只有Chrome和FireFox支援此屬性
a.download = "公司考核扣罰表.xls";

原理:

(1).blob物件本質上是js中的一個物件,裡面可以儲存大量的二進位制編碼格式的資料。建立blob物件本質上和建立一個其他物件的方式是一樣的,都是使用Blob() 的建構函式來進行建立。 建構函式接受兩個引數:

第一個引數為一個數據序列,可以是任意格式的值。

第二個引數是一個包含兩個屬性的物件{ type: MIME的型別, endings: 決定第一個引數的資料格式,可以取值為 "transparent" 或者 "native"(transparent的話不變,是預設值,native 的話按作業系統轉換) 。 }

也就是說將新建立的html轉換成了blob物件,type為表格

(2).URL.createObjectURL()方法會根據傳入的引數建立一個指向該引數物件的URL. 這個URL的生命僅存在於它被建立的這個文件裡. 新的物件URL指向執行的File物件或者是Blob物件.

語法: objectURL = URL.createObjectURL(blob || file);

引數:

File物件或者Blob物件

這裡大概說下File物件和Blob物件:

File物件,就是一個檔案,比如我用input type="file"標籤來上傳檔案,那麼裡面的每個檔案都是一個File物件.

Blob物件,就是二進位制資料,比如通過new Blob()建立的物件就是Blob物件.又比如,在XMLHttpRequest裡,如果指定responseType為blob,那麼得到的返回值也是一個blob物件.

總之,URL.createObjectURL()中可以傳blob物件,也可以傳file物件,然後生成一個指向檔案的url,將此url賦給a的href,相當於瀏覽器順著這個url找到檔案,而此檔案是個表格,就會直接下載表格而不是開啟頁面

*複製下面html並開啟就可以先體驗一下大體功能

<!DOCTYPE >
<html>
 
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	</head>
 
	<body link="blue" vlink="purple">
		<table id="print-content" border="1" cellpadding="0" cellspacing="0" style='border-collapse:collapse;table-layout:fixed;'>
			<style type="text/css">
				#red{
					color:red
				}
			</style>
			<colgroup>
				<col width="80 ">
				<col width="80 ">
				<col width="150 ">
				<col width="80 ">
				<col width="150 ">
				<col width="80 ">
				<col width="80 ">
			</colgroup>
			<tr height="20" style="text-align: center;font-size:18px">
				<td colspan="7">會簽單</td>
			</tr>
			<tr height="20" style="text-align: center;font-size:14px">
				<td></td>
				<td colspan="2">流轉</td>
				<td></td>
				<td colspan="3">會議</td>
			</tr>
			<tr height="20" style="text-align: center;font-size:14px">
				<td>名稱</td>
				<td colspan="2">自動獲取</td>
				<td>編號</td>
				<td colspan="3">自動獲取</td>
			</tr>
			<tr height="20" style="text-align: center;font-size:14px">
				<td>主持</td>
				<td colspan="2">自動獲取</td>
				<td>型別</td>
				<td colspan="3">自動獲取</td>
			</tr>
			<tr height="20" style="text-align: center;font-size:14px">
				<td>人</td>
				<td colspan="2">自動獲取</td>
				<td>日期</td>
				<td colspan="3">自動獲取</td>
			</tr>
			<tr height="100" style="text-align: center;font-size:14px">
				<td rowspan="5">內容</td>
				<td colspan="6" rowspan="5" id="red">自動獲取</td>
			</tr>
			<tr/>
			<tr/>
			<tr/>
			<tr/>
			<tr height="20" style="text-align: center;font-size:14px">
				<td>備註</td>
				<td colspan="6">自動獲取</td>
			</tr>
			<tr height="24" style="text-align: center;font-size:16px">
				<td colspan="7">意見</td>
			</tr>
			<tr height="24" style="text-align: center;font-size:14px">
				<td>序號</td>
				<td>人</td>
				<td>部門</td>
				<td>意見</td>
				<td>時間</td>
				<td>節點</td>
				<td>狀態</td>
			</tr>
			<tr height="20" style="text-align: center;font-size:14px">
				<td>1</td>
				<td>顧</td>
				<td>辦公室</td>
				<td>同意!</td>
				<td>2018/5/14 15:21</td>
				<td></td>
				<td>已提交</td>
			</tr>
		</table>
		
		<!-- 下載方法1.超連結_匯出檔案-->
		<a id="print-click">超連結_匯出表格</a>
		<input type="button" onclick="printout()" value="列印"></input>
	    <script>
			
			
			// 使用outerHTML屬性獲取整個table元素的HTML程式碼(包括<table>標籤),然後包裝成一個完整的HTML文件,設定charset為urf-8以防止中文亂碼
			var html = "<html><head><meta charset='utf-8' /></head><body>" + document.getElementById("print-content").outerHTML + "</body></html>";
			// 例項化一個Blob物件,其建構函式的第一個引數是包含檔案內容的陣列,第二個引數是包含檔案型別屬性的物件
			var blob = new Blob([html], {
				type: "application/vnd.ms-excel"
			});
			var a = document.getElementById("print-click");
			// 利用URL.createObjectURL()方法為a元素生成blob URL
			a.href = URL.createObjectURL(blob);
			// 設定檔名,目前只有Chrome和FireFox支援此屬性
			a.download = "會簽單.xls";
 
			  //列印具體實現程式碼
           function printout() {
           		debugger;
                var newWindow;
                //開啟一個新的視窗  
                newWindow = window.open();
                // 是新視窗獲得焦點  
                newWindow.focus();
                //儲存寫入內容  
                var newContent = "<html><head><meta charset='utf-8'/><title>列印</title></head><body>"
                newContent += document.getElementById("print-content").outerHTML;
                newContent += "</body></html>"
                // 將HTML程式碼寫入新視窗中  
                newWindow.document.write(newContent);
                newWindow.print();
                // close layout stream 
                newWindow.document.close();
                //關閉開啟的臨時視窗
                newWindow.close();
                return false;
           };
		</script>
	</body>
 
</html>