JavaScript調用本地打印機,打印Excel、Word文件
之前寫過一篇文章,使用java調用打印機打印Excel文件:
java調用打印機:http://blog.csdn.net/wangxiaoan1234/article/details/76032280
但是java運行與服務器上,外部訪問無法調用本地打印機。
假設項目需求爲:點擊按鈕打印某個報表(Excel)。當項目發佈到服務器上後,當使用java調用打印機,無論哪臺電腦訪問頁面,點擊打印按鈕,調用的都是java所運行的服務器上的打印機。
理想:
實際:
解決思路:
JavaScript運行在本地,使用JavaScript調用本地打印機。
想到可行方法:
- 直接調用打印機打印本地文件(IE瀏覽器用此方法)。
- java後臺將Excel轉換成html頁面,調用window.print()函數打印整個頁面(通用);
- 安裝打印插件(麻煩)
使用Spring poi將Excel、Word轉換爲html再進行打印的好處有:
- 所有瀏覽器通用
- 可以進行打印預覽
- 可視化的打印參數設置
- 我不會別的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後就可以各種調用打印了。
我採用的方法是:
- 前臺ajax訪問後臺轉換方法
- 後臺返回第58行的content字符串,這個字符串就是整個html頁面代碼。
- 將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頁面:
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文檔:
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文件時就會拋如上異常。