將table標(biāo)簽,包括tr、td等對(duì)json數(shù)據(jù)進(jìn)行拼接,將table輸出到表格上實(shí)現(xiàn),這種方法的弊端在于輸出的是偽excel,雖說(shuō)生成xls為后綴的文件,但文件形式上還是html,代碼如下
<html>
<head>
<p style="font-size: 20px;color: red;">使用table標(biāo)簽方式將json導(dǎo)出xls文件</p>
<button onclick='tableToExcel()'>導(dǎo)出</button>
</head>
<body>
<script>
const tableToExcel=()=> {
// 要導(dǎo)出的json數(shù)據(jù)
const jsonData=[
{
name:'路人甲',
phone:'123456',
email:'123@123456.com'
},
{
name:'炮灰乙',
phone:'123456',
email:'123@123456.com'
},
{
name:'土匪丙',
phone:'123456',
email:'123@123456.com'
},
{
name:'流氓丁',
phone:'123456',
email:'123@123456.com'
},
]
// 列標(biāo)題
let str='<tr><td>姓名</td><td>電話</td><td>郵箱</td></tr>';
// 循環(huán)遍歷,每行加入tr標(biāo)簽,每個(gè)單元格加td標(biāo)簽
for(let i=0 ; i < jsonData.length ; i++ ){
str+='<tr>';
for(const key in jsonData[i]){
// 增加\t為了不讓表格顯示科學(xué)計(jì)數(shù)法或者其他格式
str+=`<td>${ jsonData[i][key] + '\t'}</td>`;
}
str+='</tr>';
}
// Worksheet名
const worksheet='Sheet1'
const uri='data:application/vnd.ms-excel;base64,';
// 下載的表格模板數(shù)據(jù)
const template=`<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="http://www.w3.org/TR/REC-html40">
<head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>
<x:Name>${worksheet}</x:Name>
<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>
</x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->
</head><body><table>${str}</table></body></html>`;
// 下載模板
window.location.href=uri + base64(template);
};
// 輸出base64編碼
const base64=s=> window.btoa(unescape(encodeURIComponent(s)));
</script>
</body>
</html>
通過(guò)將json遍歷進(jìn)行字符串拼接,將字符串輸出到csv文件,代碼如下
<html>
<head>
<p style="font-size: 20px;color: red;">使用a標(biāo)簽方式將json導(dǎo)出csv文件</p>
<button onclick='tableToExcel()'>導(dǎo)出</button>
</head>
<body>
<script>
const tableToExcel=()=> {
// 要導(dǎo)出的json數(shù)據(jù)
const jsonData=[
{
name:'路人甲',
phone:'123456789',
email:'000@123456.com'
},
{
name:'炮灰乙',
phone:'123456789',
email:'000@123456.com'
},
{
name:'土匪丙',
phone:'123456789',
email:'000@123456.com'
},
{
name:'流氓丁',
phone:'123456789',
email:'000@123456.com'
},
];
// 列標(biāo)題,逗號(hào)隔開(kāi),每一個(gè)逗號(hào)就是隔開(kāi)一個(gè)單元格
let str=`姓名,電話,郵箱\n`;
// 增加\t為了不讓表格顯示科學(xué)計(jì)數(shù)法或者其他格式
for(let i=0 ; i < jsonData.length ; i++ ){
for(const key in jsonData[i]){
str+=`${jsonData[i][key] + '\t'},`;
}
str+='\n';
}
// encodeURIComponent解決中文亂碼
const uri='data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);
// 通過(guò)創(chuàng)建a標(biāo)簽實(shí)現(xiàn)
const link=document.createElement("a");
link.href=uri;
// 對(duì)下載的文件命名
link.download="json數(shù)據(jù)表.csv";
link.click();
}
</script>
</body>
</html>
純干貨,希望對(duì)給位同僚有所幫助,感謝觀看,喜歡就點(diǎn)個(gè)贊吧
avaScript在前端領(lǐng)域占據(jù)著絕對(duì)的統(tǒng)治地位,目前更是從瀏覽器到服務(wù)端,移動(dòng)端,嵌入式,幾乎所有的所有的應(yīng)用領(lǐng)域都可以使用它。技術(shù)圈有一句很經(jīng)典的話“凡是能用JavaScript實(shí)現(xiàn)的東西,最后都會(huì)用JavaScript實(shí)現(xiàn)”。
Excel 電子表格自 1980 年代以來(lái)一直為各行業(yè)所廣泛使用,至今已擁有超過(guò)3億用戶,大多數(shù)人都熟悉 Excel 電子表格體驗(yàn)。許多企業(yè)在其業(yè)務(wù)的各個(gè)環(huán)節(jié)中使用了 Excel 電子表格進(jìn)行數(shù)據(jù)管理。
作為全球領(lǐng)先的軟件開(kāi)發(fā)技術(shù)和低代碼平臺(tái)提供商,葡萄城專注開(kāi)發(fā)技術(shù)和工具已經(jīng)長(zhǎng)達(dá)四十余年,一直以來(lái)引領(lǐng)著國(guó)內(nèi)控件技術(shù)和數(shù)據(jù)分析工具的發(fā)展。SpreadJS表格控件作為葡萄城的核心產(chǎn)品,能夠完美兼容 Excel 的功能和使用體驗(yàn)并高度匹配在線辦公場(chǎng)景的需求。
SpreadJS可以為我們的Web應(yīng)用提供更好的交互體驗(yàn),以及更靈活的權(quán)限控制、數(shù)據(jù)整合、數(shù)據(jù)可視化、戰(zhàn)略績(jī)效測(cè)量 (SPM)、復(fù)雜的統(tǒng)計(jì)分析等。多年來(lái),Excel 兼容性一直是SpreadJS最重要的功能之一。
SpreadJS 提供了熟悉的 Excel 電子表格界面。用戶可以通過(guò)SpreadJS直接在頁(yè)面端導(dǎo)入和導(dǎo)出 Excel 文件——這一切無(wú)需依賴 Excel。
在本博客中,我們將介紹如何按照以下步驟在 JavaScript 中,實(shí)現(xiàn)頁(yè)面端電子表格導(dǎo)入/導(dǎo)出到 Excel:
1. 設(shè)置 JavaScript 電子表格項(xiàng)目
2. 添加 Excel 導(dǎo)入代碼
3. 將數(shù)據(jù)添加到導(dǎo)入的 Excel 文件
4. 添加迷你圖
5. 添加 Excel 導(dǎo)出代碼
首先,我們可以使用托管在 NPM 上的 SpreadJS 文件。為此,我們可以使用命令行參數(shù)進(jìn)行安裝。打開(kāi)命令提示符并導(dǎo)航到應(yīng)用程序的位置。在那里,您可以使用一個(gè)命令安裝所需的文件。
在這種情況下,我們需要基本的 Spread-Sheets 庫(kù)、Spread-ExcelIO 和 jQuery:
npm i @grapecity/spread-sheets @grapecity/spread-excelio jquery
SpreadJS 不依賴于 jQuery,但在這種情況下,我們使用它來(lái)提供簡(jiǎn)單的跨域請(qǐng)求支持,稍后我們將對(duì)其進(jìn)行回顧。
一旦安裝了這些,我們就可以在我們的代碼中添加對(duì)這些腳本和 CSS 文件的引用:
<!DOCTYPE html>
<html>
<head>
<title>SpreadJS ExcelIO</title>
<script src="./node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
<link href="./node_modules/@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="./node_modules/@grapecity/spread-sheets/dist/gc.spread.sheets.all.min.js"></script>
<script type="text/javascript" src="./node_modules/@grapecity/spread-excelio/dist/gc.spread.excelio.min.js"></script>
</head>
<body>
<div id="ss" style="height:600px; width :100%; "></div>
</body>
</html>
除了 SpreadJS 和 jQuery 文件之外,我們還需要導(dǎo)入 FileSaver 庫(kù),為了便于后續(xù)程序處理,SpreadJS默認(rèn)提供完整的文件流,F(xiàn)ileSaver庫(kù)可以用來(lái)把文件流轉(zhuǎn)成文件下載到本地。
然后我們可以在頁(yè)面中添加一個(gè)腳本來(lái)初始化 Spread.Sheets 組件和一個(gè) div 元素來(lái)包含它(因?yàn)?SpreadJS 電子表格組件使用了一個(gè)畫布,這是初始化組件所必需的):
<script type="text/javascript">
$(document).ready(function () {
var workbook=new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
});
</script>
</head>
<body>
<div id="ss" style="height:600px ; width :100%; "></div>
</body>
我們需要?jiǎng)?chuàng)建一個(gè)客戶端 ExcelIO 組件的實(shí)例,我們可以使用它來(lái)打開(kāi)文件:
var excelIO=new GC.Spread.Excel.IO();
然后我們需要添加一個(gè)函數(shù)來(lái)導(dǎo)入文件。在此示例中,我們導(dǎo)入了一個(gè)本地文件,但您可以對(duì)服務(wù)器上的文件執(zhí)行相同的操作。如果從服務(wù)器導(dǎo)入文件,您需要引用該位置。下面是一個(gè)輸入元素的示例,用戶可以在其中輸入文件的位置:
<input type="text" id="importUrl" value="http://www.testwebsite.com/files/TestExcel.xlsx" style="width:300px" />
一旦你有了它,你可以直接在腳本代碼中訪問(wèn)該值:
var excelUrl=$("#importUrl").val();
導(dǎo)入函數(shù)的以下代碼使用“excelUrl”變量的本地文件:
function ImportFile() {
var excelUrl="./test.xlsx";
var oReq=new XMLHttpRequest();
oReq.open('get', excelUrl, true);
oReq.responseType='blob';
oReq.onload=function () {
var blob=oReq.response;
excelIO.open(blob, LoadSpread, function (message) {
console.log(message);
});
};
oReq.send(null);
}
function LoadSpread(json) {
jsonData=json;
workbook.fromJSON(json);
workbook.setActiveSheet("Revenues (Sales)");
}
無(wú)論您是在服務(wù)器上還是在本地引用文件,都需要在 $(document).ready 函數(shù)內(nèi)的腳本中添加以下內(nèi)容:
$(document).ready(function () {
$.support.cors=true;
workbook=new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
//...
});
在這種情況下,我們需要啟用 Cross-Origin-Request-Support,因?yàn)槲覀兛赡軙?huì)從 URL 加載文件。因此 $.support.cors=true;行,否則嘗試加載它會(huì)導(dǎo)致 CORS 錯(cuò)誤。
我們使用本教程的“損益表”Excel 模板導(dǎo)入本地文件。
現(xiàn)在我們可以使用 Spread.Sheets 腳本在這個(gè)文件中添加另一個(gè)收入行。讓我們?cè)陧?yè)面上添加一個(gè)按鈕來(lái)執(zhí)行此操作:
<button id="addRevenue">Add Revenue</button>
我們可以為該按鈕的單擊事件處理程序編寫一個(gè)函數(shù)來(lái)添加一行并從前一行復(fù)制樣式以準(zhǔn)備添加一些數(shù)據(jù)。要復(fù)制樣式,我們需要使用 copyTo 函數(shù)并傳入:
1. 原始和目標(biāo)行和列索引
2. 行數(shù)和列數(shù)
3. 樣式的 CopyToOptions 值
document.getElementById("addRevenue").onclick=function () {
var sheet=workbook.getActiveSheet();
sheet.addRows(newRowIndex, 1);
sheet.copyTo(10, 1, newRowIndex, 1, 1, 29, GC.Spread.Sheets.CopyToOptions.style);
}
以下用于添加數(shù)據(jù)和 Sparkline 的腳本代碼將包含在此按鈕單擊事件處理程序中。對(duì)于大部分?jǐn)?shù)據(jù),我們可以使用 setValue 函數(shù)。這允許我們通過(guò)傳入行索引、列索引和值來(lái)在 Spread 中的工作表中設(shè)置值:
sheet.setValue(newRowIndex, 1, "Revenue 8");
for (var c=3; c < 15; c++) {
sheet.setValue(newRowIndex, c, Math.floor(Math.random() * 200) + 10);
}
在 P 列中設(shè)置 SUM 公式以匹配其他行并為 Q 列設(shè)置百分比:
sheet.setFormula(newRowIndex, 15, "=SUM([@[Jan]:[Dec]])")
sheet.setValue(newRowIndex, 16, 0.15);
最后,我們可以再次使用 copyTo 函數(shù)將先前行中的公式復(fù)制到 R 到 AD 列的新行,這次使用 CopyToOptions.formula:
sheet.copyTo(10, 17, newRowIndex, 17, 1, 13, GC.Spread.Sheets.CopyToOptions.formula);
現(xiàn)在,我們可以添加迷你圖來(lái)匹配其他數(shù)據(jù)行。為此,我們需要提供一系列單元格以從中獲取數(shù)據(jù)以及迷你圖的一些設(shè)置。在這種情況下,我們可以指定:
1. 單元格的范圍,我們只是將數(shù)據(jù)添加到
2. 使迷你圖看起來(lái)像同一列中的其他迷你圖的設(shè)置
var data=new GC.Spread.Sheets.Range(11, 3, 1, 12);
var setting=new GC.Spread.Sheets.Sparklines.SparklineSetting();
setting.options.seriesColor="Text 2";
setting.options.lineWeight=1;
setting.options.showLow=true;
setting.options.showHigh=true;
setting.options.lowMarkerColor="Text 2";
setting.options.highMarkerColor="Text 1";
之后,我們調(diào)用 setSparkline 方法并指定:
1. 迷你圖的位置
2. 數(shù)據(jù)的位置
3. 迷你圖的方向
4. 迷你圖的類型
5. 我們創(chuàng)建的設(shè)置
sheet.setSparkline(11, 2, data, GC.Spread.Sheets.Sparklines.DataOrientation.horizontal, GC.Spread.Sheets.Sparklines.SparklineType.line, setting);
如果您現(xiàn)在嘗試運(yùn)行代碼,它可能看起來(lái)有點(diǎn)慢,因?yàn)槊看胃臄?shù)據(jù)和添加樣式時(shí)工作簿都會(huì)重新繪制。為了顯著加快速度并提高性能,Spread.Sheets 提供了暫停繪畫和計(jì)算服務(wù)的能力。讓我們?cè)谔砑右恍屑捌鋽?shù)據(jù)之前添加代碼以暫停兩者,然后在之后恢復(fù)兩者:
workbook.suspendPaint();
workbook.suspendCalcService();
//...
workbook.resumeCalcService();
workbook.resumePaint();
添加該代碼后,我們可以在 Web 瀏覽器中打開(kāi)該頁(yè)面,并查看 Excel 文件加載到 Spread.Sheets 中并添加了收入行。重要提示:請(qǐng)記住,出于安全考慮,Chrome 不允許您打開(kāi)本地文件,因此您需要使用 Firefox 等網(wǎng)絡(luò)瀏覽器才能成功運(yùn)行此代碼。或者,從網(wǎng)站 URL 加載文件應(yīng)該可以在任何瀏覽器中正常打開(kāi)。
最后,我們可以添加一個(gè)按鈕來(lái)導(dǎo)出包含添加行的文件。為此,我們可以使用 Spread.Sheets 中內(nèi)置的客戶端 ExcelIO 代碼:
function ExportFile() {
var fileName=$("#exportFileName").val();
if (fileName.substr(-5, 5) !=='.xlsx') {
fileName +='.xlsx';
}
var json=JSON.stringify(workbook.toJSON());
excelIO.save(json, function (blob) {
saveAs(blob, fileName);
}, function (e) {
if (e.errorCode===1) {
alert(e.errorMessage);
}
});
}
該代碼從 exportFileName 輸入元素獲取導(dǎo)出文件名。我們可以定義它并讓用戶像這樣命名文件:
<input type="text" id="exportFileName" placeholder="Export file name" value="export.xlsx" />
然后我們可以添加一個(gè)按鈕來(lái)調(diào)用這個(gè)函數(shù):
<button id="export">Export File</button>
document.getElementById("export").onclick=function () {
ExportFile();
}
添加收入行后,您可以使用“導(dǎo)出文件”按鈕導(dǎo)出文件。確保添加 FileSaver 外部庫(kù)以允許用戶將文件保存在他們想要的位置:
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
成功導(dǎo)出文件后,您可以在 Excel 中打開(kāi)它,并查看文件與導(dǎo)入時(shí)的外觀相同,只是現(xiàn)在我們添加了額外的收入行。
這只是一個(gè)示例,說(shuō)明如何使用 SpreadJS JavaScript 電子表格將數(shù)據(jù)添加到 Excel 文件,然后使用簡(jiǎn)單的 JavaScript 代碼將它們導(dǎo)出回 Excel。
導(dǎo)出Excel文件這個(gè)功能,通常都是在后端實(shí)現(xiàn)返回前端一個(gè)下載鏈接,但有時(shí)候我們只想導(dǎo)出前端頁(yè)面上已經(jīng)有了的數(shù)據(jù),不想再調(diào)后端導(dǎo)出接口浪費(fèi)服務(wù)器資源,學(xué)習(xí)本文demo例子,我們踹掉后端,直接在前端導(dǎo)出Excel!
1、利用Blob對(duì)象構(gòu)造一個(gè)a標(biāo)簽的href鏈接,從而實(shí)現(xiàn)文件下載,Excel支持html格式,因此我們只需要將構(gòu)造好的html內(nèi)容放到Blob對(duì)象中,即可下載Excel表格
2、利用base64編碼構(gòu)造一個(gè)a標(biāo)簽的href鏈接,從而實(shí)現(xiàn)文件下載,同上,我們需要將構(gòu)造好的html內(nèi)容URI編碼拼到base64鏈接,即可下載Excel表格
//blob、base64轉(zhuǎn)文件下載,通過(guò)A標(biāo)簽?zāi)M點(diǎn)擊,設(shè)置文件名
/*
萬(wàn)能流 application/octet-stream
word文件 application/msword
excel文件 application/vnd.ms-excel
txt文件 text/plain
圖片文件 image/png、jpeg、gif、bmp
*/
function downloadByBlob(fileName, text) {
let a=document.createElement("a");
a.href=URL.createObjectURL(new Blob([text], {type: "application/octet-stream"}));
a.download=fileName || 'Blob導(dǎo)出測(cè)試.txt';
a.click();
a.remove();
URL.revokeObjectURL(a.href);
}
function downloadByBase64(fileName, text) {
let a=document.createElement('a');
a.href='data:application/octet-stream;base64,' + window.btoa(unescape(encodeURIComponent(text)));
a.download=fileName || 'Base64導(dǎo)出測(cè)試.txt';
a.click();
a.remove();
URL.revokeObjectURL(a.href);
}
封裝導(dǎo)出Excel表格方法
//踹掉后端,前端導(dǎo)出Excel!
function exportExcel(fileName,columns,datas){
//列名
let columnHtml="";
columnHtml +="<tr style=\"text-align: center;\">\n";
for (let key in columns) {
columnHtml +="<td style=\"background-color:#bad5fd\">"+columns[key]+"</td>\n";
}
columnHtml +="</tr>\n";
//數(shù)據(jù)
let dataHtml="";
for (let data of datas) {
dataHtml +="<tr style=\"text-align: center;\">\n";
for (let key in columns) {
dataHtml +="<td>"+data[key]+"</td>\n";
}
dataHtml +="</tr>\n";
}
//完整html
let excelHtml="<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n" +
" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n" +
" xmlns=\"http://www.w3.org/TR/REC-html40\">\n" +
"<head>\n" +
" <!-- 加這個(gè),其他單元格帶邊框 -->" +
" <xml>\n" +
" <x:ExcelWorkbook>\n" +
" <x:ExcelWorksheets>\n" +
" <x:ExcelWorksheet>\n" +
" <x:Name></x:Name>\n" +
" <x:WorksheetOptions>\n" +
" <x:DisplayGridlines/>\n" +
" </x:WorksheetOptions>\n" +
" </x:ExcelWorksheet>\n" +
" </x:ExcelWorksheets>\n" +
" </x:ExcelWorkbook>\n" +
" </xml>\n" +
" <style>td{font-family: \"宋體\";}</style>\n" +
"</head>\n" +
"<body>\n" +
"<table border=\"1\">\n" +
" <thead>\n" +
columnHtml +
" </thead>\n" +
" <tbody>\n" +
dataHtml +
" </tbody>\n" +
"</table>\n" +
"</body>\n" +
"</html>";
//下載
downloadByBlob((fileName || "導(dǎo)出Excel")+".xls",excelHtml);
}
導(dǎo)出txt文檔
downloadByBlob("downloadByBlob-導(dǎo)出txt文檔.txt","downloadByBlob\n導(dǎo)出txt簡(jiǎn)單測(cè)試\n");
downloadByBase64("downloadByBase64-導(dǎo)出txt文檔.txt","downloadByBase64\n導(dǎo)出txt簡(jiǎn)單測(cè)試\n");
導(dǎo)出Excel表格
exportExcel("xx業(yè)務(wù)Excel導(dǎo)出", {"id": "編號(hào)", "name": "名字", "age": "年齡", "time": "參加工作時(shí)間"}, [{
"id": "A001",
"name": "張三",
"age": "18",
"time": new Date().toLocaleString()
},{
"id": "A002",
"name": "李四",
"age": "20",
"time": new Date().toLocaleString()
}]);
導(dǎo)出word文檔也是一樣
參考上我們之前的《FreeMarker模板引擎》,先畫好我們想要的文檔格式然后轉(zhuǎn)成xml,調(diào)用我們封裝好的方法,將構(gòu)造好的xml內(nèi)容轉(zhuǎn)成文件,實(shí)現(xiàn)前端導(dǎo)出復(fù)雜格式文檔!
如果有復(fù)雜數(shù)據(jù),建議還是在后端操作,當(dāng)然你也可以把數(shù)據(jù)返回前端在前端導(dǎo)出也行
前端導(dǎo)出Excel主要是利用Bolb、base64,以及Excel支持html格式的特性,這個(gè)特性不僅前端可以利用,后端也一樣可以,這里也分享一下后端工具類,原理都是一樣的
package cn.huanzi.qch.util;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Excel工具類
*/
public class ExcelUtil {
/**
* 導(dǎo)出
* 無(wú)需依賴POI
*/
/*
示例:
try {
//列名
LinkedHashMap<String, String> columns=new LinkedHashMap<>(4);
columns.put("id","編號(hào)");
columns.put("name","名字");
columns.put("age","年齡");
columns.put("time","參加工作時(shí)間");
//數(shù)據(jù)
List<Map<String, Object>> datas=new ArrayList<>(3);
HashMap<String, Object> hashMap=new HashMap<>();
hashMap.put("id","A001");
hashMap.put("name","張三");
hashMap.put("age",18);
hashMap.put("time",new Date());
datas.add(hashMap);
//帶換行符:
HashMap<String, Object> hashMap2=new HashMap<>();
hashMap2.put("id","A002");
hashMap2.put("name","李四
李四1
李四2");
hashMap2.put("age",20);
hashMap2.put("time",new Date());
datas.add(hashMap2);
HashMap<String, Object> hashMap3=new HashMap<>();
hashMap3.put("id","A003");
hashMap3.put("name","王五");
hashMap3.put("age",25);
hashMap3.put("time",new Date());
datas.add(hashMap3);
//導(dǎo)出
ExcelUtil.exportByResponse(this.getResponse(),"Excel導(dǎo)出測(cè)試",columns,datas);
//ExcelUtil.exportByFile(new File("D:\\XFT User\\Downloads\\Excel導(dǎo)出測(cè)試.xls"),columns,datas);
} catch (Exception e) {
e.printStackTrace();
}
*/
public static void exportByResponse(HttpServletResponse response, String fileName, LinkedHashMap<String, String> columns, List<Map<String, Object>> datas) throws Exception {
response.addHeader("Content-disposition", "attachment; filename=" + fileName + ".xls");
response.setContentType("application/ms-excel");
StringBuilder sb=exportOfData(columns, datas);
OutputStream out=response.getOutputStream();
out.write(sb.toString().getBytes("UTF-8"));
out.flush();
out.close();
}
public static void exportByFile(File file, LinkedHashMap<String, String> columns, List<Map<String, Object>> datas) {
StringBuilder sb=exportOfData(columns, datas);
try (PrintWriter myFile=new PrintWriter(file,"UTF-8")) {
myFile.println(sb);
} catch (Exception e) {
System.err.println("exportByFile(),操作出錯(cuò)...");
e.printStackTrace();
}
System.out.println(file.getName() + ",操作完成!");
}
//其他單元格無(wú)邊框
private static StringBuilder exportOfData(LinkedHashMap<String, String> columns, List<Map<String, Object>> datas) {
StringBuilder sb=new StringBuilder("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"" +
" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"" +
" xmlns=\"http://www.w3.org/TR/REC-html40\">");
//加這個(gè),其他單元格帶邊框
sb.append("<head>" +
" <xml>" +
" <x:ExcelWorkbook>" +
" <x:ExcelWorksheets>" +
" <x:ExcelWorksheet>" +
" <x:Name></x:Name>" +
" <x:WorksheetOptions>" +
" <x:DisplayGridlines/>" +
" </x:WorksheetOptions>" +
" </x:ExcelWorksheet>" +
" </x:ExcelWorksheets>" +
" </x:ExcelWorkbook>" +
" </xml>" +
" <style>td{font-family: \"宋體\";}</style>" +
"</head>");
sb.append("<body>");
sb.append("<table border=\"1\">");
//列名
sb.append("<tr style=\"text-align: center;\">");
for (Map.Entry<String, String> entry : columns.entrySet()) {
sb.append("<td style=\"background-color:#bad5fd\">" + entry.getValue() + "</td>");
}
sb.append("</tr>");
//數(shù)據(jù)
for (Map<String, Object> data : datas) {
sb.append("<tr style=\"text-align: center;\">");
for (Map.Entry<String, String> entry : columns.entrySet()) {
Object dataValue=data.get(entry.getKey());
//如果是日期類型
if (dataValue instanceof java.util.Date) {
dataValue=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dataValue);
}
sb.append("<td>" + dataValue.toString() + "</td>");
}
sb.append("</tr>");
}
sb.append("</table>");
sb.append("</body>");
sb.append("</html>");
return sb;
}
//前端導(dǎo)出Excel
/*
示例:
exportExcel("xx業(yè)務(wù)Excel導(dǎo)出", {"id": "編號(hào)", "name": "名字", "age": "年齡", "time": "參加工作時(shí)間"}, [{
"id": "A001",
"name": "張三",
"age": "18",
"time": new Date().toLocaleString()
},{
"id": "A002",
"name": "李四",
"age": "20",
"time": new Date().toLocaleString()
}]);
*/
/*
//blob、base64轉(zhuǎn)文件下載,通過(guò)A標(biāo)簽?zāi)M點(diǎn)擊,設(shè)置文件名
//萬(wàn)能流 application/octet-stream
//word文件 application/msword
//excel文件 application/vnd.ms-excel
//txt文件 text/plain
//圖片文件 image/png、jpeg、gif、bmp
function downloadByBlob(fileName, text) {
let a=document.createElement("a");
a.href=URL.createObjectURL(new Blob([text], {type: "application/octet-stream"}));
a.download=fileName || 'Blob導(dǎo)出測(cè)試.txt';
a.click();
a.remove();
URL.revokeObjectURL(a.href);
}
function downloadByBase64(fileName, text) {
let a=document.createElement('a');
a.href='data:application/octet-stream;base64,' + window.btoa(unescape(encodeURIComponent(text)));
a.download=fileName || 'Base64導(dǎo)出測(cè)試.txt';
a.click();
a.remove();
URL.revokeObjectURL(a.href);
}
//踹掉后端,前端導(dǎo)出Excel!
function exportExcel(fileName,columns,datas){
//列名
let columnHtml="";
columnHtml +="<tr style=\"text-align: center;\">\n";
for (let key in columns) {
columnHtml +="<td style=\"background-color:#bad5fd\">"+columns[key]+"</td>\n";
}
columnHtml +="</tr>\n";
//數(shù)據(jù)
let dataHtml="";
for (let data of datas) {
dataHtml +="<tr style=\"text-align: center;\">\n";
for (let key in columns) {
dataHtml +="<td>"+data[key]+"</td>\n";
}
dataHtml +="</tr>\n";
}
//完整html
let excelHtml="<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n" +
" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n" +
" xmlns=\"http://www.w3.org/TR/REC-html40\">\n" +
"<head>\n" +
" <!-- 加這個(gè),其他單元格帶邊框 -->" +
" <xml>\n" +
" <x:ExcelWorkbook>\n" +
" <x:ExcelWorksheets>\n" +
" <x:ExcelWorksheet>\n" +
" <x:Name></x:Name>\n" +
" <x:WorksheetOptions>\n" +
" <x:DisplayGridlines/>\n" +
" </x:WorksheetOptions>\n" +
" </x:ExcelWorksheet>\n" +
" </x:ExcelWorksheets>\n" +
" </x:ExcelWorkbook>\n" +
" </xml>\n" +
" <style>td{font-family: \"宋體\";}</style>\n" +
"</head>\n" +
"<body>\n" +
"<table border=\"1\">\n" +
" <thead>\n" +
columnHtml +
" </thead>\n" +
" <tbody>\n" +
dataHtml +
" </tbody>\n" +
"</table>\n" +
"</body>\n" +
"</html>";
//下載
downloadByBlob((fileName || "導(dǎo)出Excel")+".xls",excelHtml);
}
*/
}
作者:huanzi-qch
出處:https://www.cnblogs.com/huanzi-qch
若標(biāo)題中有“轉(zhuǎn)載”字樣,則本文版權(quán)歸原作者所有。若無(wú)轉(zhuǎn)載字樣,本文版權(quán)歸作者所有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文鏈接,否則保留追究法律責(zé)任的權(quán)利.
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。