Javascript导出Excel

  1. 引用ExcelBuilder
  2. 创建workbook
    var workbook = ExcelBuilder.createWorkbook();
  3. 创建worksheet
    var worksheet = workbook.createWorksheet({name: 'Sheet 1'});
    workbook.addWorksheet(worksheet);
  4. 加载数据
    var data = [['Name','Gender','Age']];
    data.push(['Zhang San','M', 24]);
    data.push(['Li Si','F', 18]);
    data.push(['Wang Wu','M', 22]);
    worksheet.setData(data);
  5. 下载
    var blob = ExcelBuilder.createFile(workbook, {type:'blob'});
    var url = URL.createObjectURL(blob);
    var a = document.createElement('A');
    a.href = url;
    a.download = Date.now()+'.xlsx';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    
    
  • 自动计算列宽
    //定义每个单字节的宽度
    var LETTER_WIDTH = 1.11;
    
    //定义每列最大宽度
    var MAX_COLUMN_WIDTH = 80;
    
    //定义每列的最小宽度
    var columns = [
    	{width: 10},
    	{width: 10},
    	{width: 10}
    ];
    
    //添加数据时遍历每一行,计算最大宽度
    var autoFitWidth = function(row) {
    	$.each(row, function(i,str){
    		if(str!==null&&str!==undefined&&str!=='') {
    			//英文占一个字节宽度,中文占两个
    			var match = str.toString().match(/[\\0-\\255]/ig);
    			var en = match==null?0:match.length;
    			var w = (str.length * 2 - en) * LETTER_WIDTH;
    			columns[i].width = Math.min(Math.max(columns[i].width, w), MAX_COLUMN_WIDTH);
    		}
    	});
    };
    
    //遍历完数据后将列的设置添加到worksheet中
    worksheet.setColumns(columns);
  • 过滤特殊字符
    //一些特殊字符会导致excel报错
    var specialChar = /[\u0000-\u0008\u000b\u000c\u000d-\u001f]/ig;
    val = val.replace(specialChar,'');
  • 自动换行,顶部对齐
    //创建一种样式
    var format1 = workbook.getStyleSheet().createFormat({
    	alignment:{
    		vertical:'top',
    		wrapText: true
    	}
    });
    //填充数据,给单元格增加样式
    var data = [
    	[
    		{value:'row1_col1\nline2\nline3','metadata':{'style':format1}},
    		{value:'row1_col2'},
    		'row_col3'
    	],
    	[
    		'row2_col1','row2_col2','row2_col3'
    	]
    ]
  • 全局默认样式
    workbook.getStyleSheet().masterCellFormats[0].alignment ={
    	vertical:'top',
    	wrapText: true
    };

     

 

Angular Js 事件传递、广播、Controller间数据交互

架设有这么三个Controller,Golbal在外面,另外两个在里面

  • GlobalController
    • UserListController
    • UserDetailController

UserListController触发一个事件change_user冒泡到GlobalController中

$scope.selectUser = function(user) {
    $scope.active_uid = user.uid;
    $scope.$emit('change_user',user.uid,user);//后面可以传若干个参数
};

 

GlobalController响应这个事件

$scope.$on('change_user', function(event,uid,user){
    //TODO something
});

 

GlobalController广播一个事件到自己和所有的子Controller中

$scope.$on('change_user', function(event,uid,user){
    $scope.$broadcast('parent_change_user',uid,user);//如果写成change_user就死循环了,因为这里广播的事件自己也能响应
});

 

UserDetailController接收广播

$scope.$on('parent_change_user', function(event,uid,user){
    //TODO something
});

 

JS/CSS判断是否是retina屏幕

JS:

if(window.devicePixelRatio > 1){
    //是retina屏幕
}

 

CSS:

@media screen and (-webkit-min-device-pixel-ratio: 1.5),
screen and (-moz-min-device-pixel-ratio: 1.5) ,
screen and (-ms-min-device-pixel-ratio: 1.5) ,
screen and (-o-min-device-pixel-ratio: 1.5) ,
screen and (min-device-pixel-ratio: 1.5) {
    .test {
        /*是retina屏*/
    }
}

 

ios版QQ中锚点和hashchange的BUG

问题

QQ版本:5.6 for iPhone

首先是这样一段代码,正常情况下点击A标签location的hash会变成#one,并触发hashchange事件,页面不会刷新。

再执行history.back()或点击浏览器的后退按钮时,会再次触发hashchange事件,页面也不会刷新

<a href="#one">test</a>
<script>
	window.onhashchange = function() {
		alert('onhashchange');
	}
</script>

但是在ios的QQ中点击A标签会刷新页面后条转到#one处,不会触发hashchange事件。

再执行history.back()或点击浏览器的后退按钮时,同样不会触发hashchange事件,并且是以重新加载页面的方式返回的。

感觉在ios的QQ中锚点链接被当成了普通链接进行处理了。

尝试解决

然后稍微做了一些调整,将href=”#one”改成了通过js执行location.hash=”#one”。

<a href="javascript:void(0);" onclick="location.hash='#one'">test</a>
<script>
	window.onhashchange = function() {
		alert('onhashchange');
	}
</script>

这么写之后点击a标签页面不会刷新了,location.hash也变成了#one,但是却没有触发hashchange事件。

最终解决

改用popstate事件,不知道为什么在ios的QQ中onload的时候会触发popstate事件,history.back时也会触发这个事件。

<a href="javascript:void(0);" onclick="location.hash='#one'">test</a>
<script>
	function test() {
		alert('onhashchange or onpopstate')
	}
	if(/iPhone\sOS.*QQ[^B]/.test(navigator.userAgent)) {
		window.onpopstate = test;
	} else {
		window.onhashchange = test;
	}
</script>

用正则判断了一下userAgent,如果是在ios的QQ中就使用popstate,其它情况还是用hashchange

-webkit-mask

-webkit-mask的写法和background一样,效果是在background上添加一层蒙板,只能用mask的图片透明度影响background的透明度,无法影响background的rgb色值。

-webkit-mask: url(icon.png) -125px 0;
-webkit-mask-size: 150px 100px;
background: none orange;

base64透明图

1:1 (640×640)

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=

2:1 (640×320)

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAMAAADD/I+4AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF////AAAAVcLTfgAAAA1JREFUeNpiYGAACDAAAAMAAdNjUbYAAAAASUVORK5CYII=

16:9 (640×360)

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAJAQMAAAAB5D5xAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjwA0AABsAAQrj5HwAAAAASUVORK5CYII=

5:3 (600×360)

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAADCAMAAABs6DXKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF////AAAAVcLTfgAAAA5JREFUeNpiYEAHAAEGAAASAAGzTHsVAAAAAElFTkSuQmCC

64:15 (640×150)

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAPAQMAAABuqVskAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAAtJREFUCNdjGBwAAACHAAGSlBfhAAAAAElFTkSuQmCC

32:15 (640×300)

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAPAQMAAAC/Tl9UAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAAtJREFUCNdjoB4AAABLAAGYraT+AAAAAElFTkSuQmCC

64:45 (640×450)

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAtAQMAAAAkzf8ZAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA1JREFUGNNjGAWDDwAAAZUAAS+WdwMAAAAASUVORK5CYII=

Keycode对照表

字母和数字键的键码值(keyCode)
按键键码按键键码按键键码按键键码
A65J74S83149
B66K75T84250
C67L76U85351
D68M77V86452
E69N78W87553
F70O79X88654
G71P80Y89755
H72Q81Z90856
I73R82048957
数字键盘上的键的键码值(keyCode)功能键键码值(keyCode)
按键键码按键键码按键键码按键键码
0968104F1112F7118
1979105F2113F8119
298*106F3114F9120
399+107F4115F10121
4100Enter108F5116F11122
5101109F6117F12123
6102.110
7103/111
控制键键码值(keyCode)
按键键码按键键码按键键码按键键码
BackSpace8Esc27Right Arrow39-_189
Tab9Spacebar32Dw Arrow40.>190
Clear12Page Up33Insert45/?191
Enter13Page Down34Delete46`~192
Shift16End35Num Lock144[{219
Control17Home36;:186\|220
Alt18Left Arrow37=+187]}221
Cape Lock20Up Arrow38,<188‘”222
多媒体键码值(keyCode)
按键键码按键键码按键键码按键键码
音量加175
音量减174
停止179
静音173
浏览器172
邮件180
搜索170
收藏171

 

 

CSS重新定义select样式(含下拉箭头)

先用appearance:none取消浏览器默认样式,再用多重背景定义背景色和箭头
select {
	@include appearance(none);
	@include background-image(inline-image("select_arrow.png"),linear-gradient(top, #ffffff 0%,#e8e8e8 100%));
	background-repeat: no-repeat, repeat-x;
	background-position: right center, right top ;
	background-size: auto 100%, 100% 100%;&nbsp;
}