Jack Huang's Blog


  • 首页

  • 标签

  • 归档

  • 搜索

Expressjs cors入门简介

发表于 2019-07-24

在nodejs+expressjs+vuejs的解决方案中,服务器端应用开发和前端应用的开发是独立的。不过前端应用调用服务器端应用的RESTful API时涉及跨域资源访问,因此需要添加expressjs的cors模块。下面简要介绍cors模块的使用方法。

跨域资源共享简介

跨域资源共享(CORS)是一种机制,允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。网页可以自由嵌入跨源图像,样式表,脚本,iframe和视频。但某些“跨域”请求,尤其是Ajax请求,默认情况下是由同源安全策略禁止的。

CORS定义了一种浏览器和服务器可以交互的方式,以确定允许跨源请求是否安全。它允许比纯粹的同源请求更多的自由和功能,但比简单地允许所有跨源请求更安全。 CORS规范最初是作为W3C建议书发布的,但该文件已经过时。目前主动维护的CORS定义规范是WHATWG的Fetch Living Standard。

CORS标准描述了新的HTTP标头,它为浏览器提供了一种仅在获得许可时才能请求远程URL的方法。 尽管服务器可以执行某些验证和授权,但浏览器通常负责支持这些标头并遵守它们所施加的限制。

对于可以修改数据的Ajax和HTTP请求方法(通常是GET以外的HTTP方法,或者某些MIME类型的POST用法),规范要求浏览器“预检”请求,通过HTTP OPTIONS请求从服务器请求支持的方法 方法,然后,在服务器“批准”时,使用实际的HTTP请求方法发送实际请求。 服务器还可以通知客户端是否应该随请求一起发送“凭证”(包括Cookie和HTTP身份验证数据)。

跨域资源共享流程图

图1 跨域资源共享流程图

CORS安装

CORS是一个node.js包,用于提供Connect / Express中间件,可用于启用具有各种选项的CORS。使用如下方式安装。

1
npm install cors --save

CORS示例

  • 简单示例,允许所有跨域请求
1
2
3
4
5
6
7
8
9
10
11
12
13
var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})

参考链接

  1. Cross-origin resource sharing,by wikipedia.
  2. 跨域资源共享 CORS 详解,by 阮一峰.
  3. cors,by expressjs.com.

nodemon入门简介

发表于 2019-07-23

Nodemon是一个用于nodejs开发的工具程序,它将监视nodejs源中的任何更改并自动重新启动服务器。

nodemon不需要对代码或开发方法进行任何其他更改。 nodemon是node的替换包装器,在执行脚本时使用nodemon替换命令行上的单词node即可。

安装

1
npm install -g nodemon

使用

1
nodemon [your node app]

参考链接

  1. nodemon,by remy.
  2. 在 Express 开发中使用 nodemon,by bubkoo.

RESTful_API设计及测试入门

发表于 2019-07-23 | 更新于 2019-07-24

RESTful API是目前比较成熟的一套互联网应用程序的API设计理论,提供了一种统一的机制,方便不同的前端设备与后端进行通信,以应对前端设备层出不穷(手机、平板、桌面电脑、其他专用设备……)的状况。同时对开发人员而言,提供了一种规范,方便协作开发,降低了API接口设计的难度。

RESTful API设计规范

请参考阮一峰老师的RESTful API 设计指南。

RESTful API的测试方法

RESTful API设计好了之后,需要测试其可用性。常用的API测试工具有Postman。简单入门可参考Postman 安装及使用入门教程。

Postman中使用HTTP POST方法测试RESTful API时,需要了解POST提交数据的方法。

POST提交数据的方法

POST 几种请求主要包括 application/x-www-form-urlencoded、 multipart/form-data、 application/json、text/xml 四种的方法。

服务端通常是根据请求头(Request Headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。
POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。

  • application/x-www-form-urlencoded (默认常用)

这是最常见的 POST 提交数据的方式。浏览器的原生表单,如果不设置Content-type属性,就会默认该方式提交数据,并且提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。

  • multipart/form-data

这是另一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让表单的enctyped等于 multipart/form-data。

  • application/json

application/json 这种方案,可以方便的提交复杂的结构化数据,这种POST提交方式越来越多,用来告诉服务端消息主体是序列化后的 JSON 字符串。

由于JSON规范的流行,出了低版本的IE之外,各大浏览器都支持 JSON.stringify 将JSON数据字符串化(编码)传到服务器,还可以通过 JSON.parse 将字符串转化(解码)为JSON数据供前端渲染或者其他处理。

  • text/xml

现在基本不用。

参考链接

  1. RESTful API 设计指南,by 阮一峰.
  2. RESTful API 设计最佳实践,by Philipp Hauer.
  3. restful-api-design-references,by aisuhua.
  4. Postman Doc,by postman homepage.
  5. Postman 安装及使用入门教程,by Mafly.
  6. 四种常见的 POST 提交数据方式,by Jerry Qu.

HTML_DOM文档对象模型简介

发表于 2019-07-22 | 更新于 2023-04-01

最近要写一些八股文,上网一搜,好多范例,正想下载下来借鉴以下,可惜不让复制粘贴。不过难不倒我,直接使用文档对象模型(Document Object Model,DOM)提供编程接口,将整篇文章下来。

DOM概述

DOM简介

文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。

一个web页面是一个文档。这个文档可以在浏览器窗口或作为HTML源码显示出来。但上述两个情况中都是同一份文档。文档对象模型(DOM)提供了对同一份文档的另一种表现,存储和操作的方式。 DOM是web页面的完全的面向对象表述,它能够使用如 JavaScript等脚本语言进行修改。

DOM 和 JavaScript

开始的时候,JavaScript和DOM是交织在一起的,但它们最终演变成了两个独立的实体。JavaScript可以访问和操作存储在DOM中的内容,因此我们可以写成这个近似的等式:

1
API (web 或 XML 页面) = DOM + JS (脚本语言)

DOM 被设计成与特定编程语言相独立,使文档的结构化表述可以通过单一,一致的API获得。尽管通常使用JavaScript操作DOM, 但DOM 也可以使用其他的语言来实现。

DOM访问

在使用DOM时,您不需要做任何其他特殊的操作。不同的浏览器都有对DOM不同的实现, 这些实现对当前的DOM标准而言,都会呈现出不同程度的一致性,每个web浏览器都会使用一些文档对象模型,从而使页面可以被脚本语言访问。

当您在创建一个脚本时-无论是使用内嵌 <script>元素或者使用在web页面脚本加载的方法— 您都可以使用 document或 window 元素的API来操作文档本身或获取文档的子类(web页面中的各种元素)。

您的DOM编程代码可能会像下面例子一样非常简单,如使用 window对象的alert()函数显示一个警告信息,或者使用比较复杂的方法来创建一个新的内容,如下面内容较长的实例所示。

1
<body onload="window.alert('welcome to my home page!');">

重要的数据类型

为简单起见,在API参考文档中的语法实例通常会使用element(s) 指代节点,使用nodeList(s)或 element(s)来指代节点数组,使用 attribute(s)来指代属性节点。

数据类型 解释
document 当一个成员返回 document 对象 (例如,元素的 ownerDocument 属性返回它所属于 document ) ,这个对象就是root document 对象本身。 DOM document Reference 一章对 document 对象进行了描述。
element element 是指由 DOM API 中成员返回的类型为 element 的一个元素或节点。 例如, document.createElement() 方法会返回一个 node 的对象引用,也就是说这个方法返回了在DOM中创建的 element。 element 对象实现了 DOM Element 接口以及更基本的 Node 接口,参考文档将两者都包含在内。
nodeList nodeList 是一个元素的数组,如从 document.getElementsByTagName() 方法返回的就是这种类型。 nodeList 中的条目由通过下标有两种方式进行访问:list.item(1)和list[1]。两种方式是等价的,第一种方式中 item() 是 nodeList 对象中的单独方法。 后面的方式则使用了经典的数组语法来获取列表中的第二个条目。
attribute 当 attribute 通过成员函数 (例如,通过 createAttribute()方法) 返回时,它是一个为属性暴露出专门接口的对象引用。DOM中的属性也是节点,就像元素一样,只不过您可能会很少使用它。
namedNodeMap namedNodeMap 和数组类似,但是条目是由name或index访问的,虽然后一种方式仅仅是为了枚举方便,因为在 list 中本来就没有特定的顺序。 出于这个目的, namedNodeMap 有一个 item() 方法,你也可以从 namedNodeMap 添加或移除条目。

DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。

节点的类型有七种。

  • Document:整个文档树的顶层节点
  • DocumentType:doctype标签(比如<!DOCTYPE html>)
  • Element:网页的各种HTML标签(比如<body>、<a>等)
  • Attribute:网页元素的属性(比如class=”right”)
  • Text:标签之间或标签包含的文本
  • Comment:注释
  • DocumentFragment:文档的片段

浏览器提供一个原生的节点对象Node,上面这七种节点都继承了Node,因此具有一些共同的属性和方法。

DOM中核心接口

在DOM编程时,通常使用的最多的就是 Document 和 window 对象。简单的说, window 对象表示浏览器中的内容,而 document 对象是文档本身的根节点。Element 继承了通用的 Node 接口, 将这两个接口结合后就提供了许多方法和属性可以供单个元素使用。在处理这些元素所对应的不同类型的数据时,这些元素可能会有专用的接口,如上节中的 table 对象的例子。

下面是在web和XML页面脚本中使用DOM时,一些常用的API简要列表。

  • document.getElementById(id)
  • document.getElementsByTagName(name)
  • document.createElement(name)
  • parentNode.appendChild(node)
  • element.innerHTML
  • element.style.left
  • element.setAttribute()
  • element.getAttribute()
  • element.addEventListener()
  • window.content
  • window.onload
  • window.dump()
  • window.scrollTo()

Element的尺寸

  • scrollWidth:对象的实际内容的宽度,不包边线宽度,会随对象中内容超过可视区后而变大。
  • clientWidth:对象内容的可视区的宽度,不包滚动条等边线,会随对象显示大小的变化而改变。
  • offsetWidth:对象整体的实际宽度,包滚动条等边线,会随对象显示大小的变化而改变。

当元素内容没有超过可视区域

元素内无内容或者内容不超过可视区,滚动不出现或不可用的情况下。

scrollWidth=clientWidth,两者皆为内容可视区的宽度。

offsetWidth为元素的实际宽度。

文档下载实战

以示例范文为例,提取其中内容。

禁止复制粘贴的原理

  • 阻止默认的事件响应
1
2
3
4
5
6
7
8
9
10
11
12
<script type="text/javascript">
// 禁止右键菜单
document.oncontextmenu = function(){ return false; };
// 禁止文字选择
document.onselectstart = function(){ return false; };
// 禁止复制
document.oncopy = function(){ return false; };
// 禁止剪切
document.oncut = function(){ return false; };
// 禁止粘贴
document.onpaste = function(){ return false; };
</script>
  • CSS阻止用户选择
1
2
3
element.style {
user-select: none;
}

破解禁止复制粘贴

使用chrome打开该网页,在使用快捷键ctrl+shift+i,打开开发者工具,找到文档节点DIV的id为article,使用如下代码提取文章内容:

1
2
var node=document.getElementById('article')
console.log(node.innerText)

DOM事件机制

请参考DOM的事件机制,以及事件的捕获与冒泡。

参考链接

  1. DOM 模型概述,by 阮一峰.
  2. DOM概述,by MDN web DOC.
  3. 网页上如何实现禁止复制粘贴以及如何破解,by 小茗同学.
  4. scrollWidth,clientWidth,offsetWidth等等的区别,by 南果梨.
  5. javascript中top、clientTop、scrollTop、offsetTop的讲解,by 小豆soybean.
  6. 令人头疼的clientTop、scrollTop、offsetTop,by 凌晨风.
  7. DOM的事件机制,以及事件的捕获与冒泡,by 墨城之左.
  8. DOM事件机制以及事件委托总结,by 余小兔.

Vue-cli-3集成jQWidgets

发表于 2019-07-19

jQWidgets是一个软件框架,包含小部件,主题,输入验证,拖放插件,数据适配器,内置WAI-ARIA可访问性,国际化和MVVM支持。它建立在开放标准和技术HTML5,CSS,JavaScript和jQuery之上。该库用于开发响应式Web和移动应用程序。下面介绍在Vuejs中集成jQWidgets。

安装环境

  • node.js: v10.16.0
  • npm: 6.9.0
  • vue: 2.6.10
  • cesium: 1.45.0
  • vue-cli: 3.9.2
  • webpack: 4.28.4

安装步骤

  • 安装vue-cli
1
npm install -g @vue/cli
  • 创建应用
1
vue create jqwidgets-vue-cli-app   //Choose the default preset
  • 导航到应用
1
cd jqwidgets-vue-cli-app
  • 安装jQWidgets依赖
1
npm install jqwidgets-scripts --save--dev
  • 从node_modules/jqwidgets-scripts/jqwidgets复制styles文件夹到public文件夹。

  • 在index.html链接 jqx.base.css 文件。

1
<link rel="stylesheet" type="text/css" href="./styles/jqx.base.css" />
  • 修改App.vue如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<JqxBarGauge ref="barGaugeReference"
:width="600" :height="600"
:values="values" :formatFunction="formatFunction"
/>
</template>

<script>
import JqxBarGauge from 'jqwidgets-scripts/jqwidgets-vue/vue_jqxbargauge.vue';

export default {
components: {
JqxBarGauge
},
data: function () {
return {
values: [10, 20, 30, 40, 50]
}
},
methods: {
formatFunction: function (value, index, color) {
return color;
}
}
}
</script>
  • 运行Vue Cli开发服务器
1
npm run serve
  • 在浏览器中输入 localhost:8080 查看结果。

参考链接

  1. Vue CLI with jQWidgets,by jQWidgets.

Vue-cli 3集成Cesium

发表于 2019-07-18 | 更新于 2023-07-14

之前记录了在Vue-Cli 2的基础上集成了Cesium,但现在Vue-Cli已更新到3,之前方法已不适用。在参考Vue-cli 3.0 + cesium 构建的基础上,验证记录Vue-Cli 3脚手架工具中集成Cesium的过程。

安装环境

  • node.js: v10.16.0
  • npm: 6.9.0
  • vue: 2.6.10
  • cesium: 1.45.0
  • vue-cli: 3.9.2
  • webpack: 4.28.4

安装配置

  • 安装nodejs

  • 安装vue-cli脚手架

1
2
3
4
npm install -g @vue/cli
vue create my-project
cd my-project
npm run serve
  • 安装 cesium
1
npm i cesium --save
  • 新建 vue.config.js 文件,配置内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const CopyWebpackPlugin = require('copy-webpack-plugin')
const webpack = require('webpack')
const path = require('path')

const debug = process.env.NODE_ENV !== 'production'
let cesiumSource = './node_modules/cesium/Source'
let cesiumWorkers = '../Build/Cesium/Workers'
module.exports = {
baseUrl: '',
devServer: {
port: 9999
},
configureWebpack: {
output: {
sourcePrefix: ' '
},
amd: {
toUrlUndefined: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': path.resolve('src'),
'cesium': path.resolve(__dirname, cesiumSource)
}
},
plugins: [
new CopyWebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers'}]),
new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Assets'), to: 'Assets'}]),
new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets'}]),
new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'ThirdParty/Workers'), to: 'ThirdParty/Workers'}]),
new webpack.DefinePlugin({
CESIUM_BASE_URL: JSON.stringify('./')
})
],
module: {
unknownContextCritical: /^.\/.*$/,
unknownContextCritical: false

}
}
}
  • 在 src/components 下新建 CesiumViewer.vue 文件,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div id="cesiumContainer" class="fullSize">

</div>
</template>

<script>
export default {
name: "CesiumViewer"
}
</script>

<style scoped>
.fullSize {
display: block;
position: absolute;
top: 0;
left: 0;
border: none;
width: 100%;
height: 100%;
}
</style>
  • 修改 router.js ,引入 CesiumViewer组件,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Vue from 'vue'
import Router from 'vue-router'
import CesiumViewer from './components/CesiumViewer.vue'

Vue.use(Router)

export default new Router({
routes: [
{
path: '/',
name: 'CesiumViewer',
component: CesiumViewer
}
]
})
  • 修改App.vue ,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div id="app">
<router-view/>
</div>
</template>

<style lang="css">
html, body, #cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
  • 最后修改 main.js 内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Cesium from 'cesium/Cesium'
// noinspection ES6UnusedImports
import widget from 'cesium/Widgets/widgets.css'

Vue.config.productionTip = false

new Vue({
router,
store,
render: h => h(App),
mounted () {
var viewer = new Cesium.Viewer('cesiumContainer')
}
}).$mount('#app')
  • 最后 npm serve ,打开浏览器输入localhost:8080查看效果。

注意事项

不应将viewer定义在vue组件的data对象中,因为vue会劫持数据,导致cesium卡顿。具体请参考vue+cesium cesium数据量太大导致浏览器卡顿解决办法。

参考链接

  1. Vue-cli 3.0 + cesium 构建,by QingMings.
  2. cesium-and-webpack,by marsgis.
  3. Vue.js集成Cesium,by jack huang.
  4. Cesium笔记 — Vue+Cesium开发环境搭建(基于Cesium1.69),by 芒果香蕉.
  5. vue+cesium cesium数据量太大导致浏览器卡顿解决办法,by 浮年似水.

Vue.js开发入门简易教程

发表于 2019-07-18

Vue.js(/vjuː/,或简称为Vue)是一个用于创建用户界面的开源JavaScript框架,也是一个创建单页应用的Web应用框架。Vue与React、Angular一起成为当前三大最流行的Web应用框架。下面简单介绍使用Vue CLI脚手架工具创建简单的Web应用。

Vue CLI简介

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供:

  • 通过 @vue/cli 搭建交互式的项目脚手架。
  • 通过 @vue/cli + @vue/cli-service-global 快速开始零配置原型开发。
  • 一个运行时依赖 (@vue/cli-service),该依赖:
    • 可升级;
    • 基于 webpack 构建,并带有合理的默认配置;
    • 可以通过项目内的配置文件进行配置;
    • 可以通过插件进行扩展。
  • 一个丰富的官方插件集合,集成了前端生态中最好的工具。
  • 一套完全图形化的创建和管理 Vue.js 项目的用户界面。

Vue CLI 致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。与此同时,它也为每个工具提供了调整配置的灵活性,无需 eject。

Vue CLI 有几个独立的部分:

  • CLI

CLI (@vue/cli) 是一个全局安装的 npm 包,提供了终端里的 vue 命令。它可以通过 vue create 快速创建一个新项目的脚手架,或者直接通过 vue serve 构建新想法的原型。你也可以通过 vue ui 通过一套图形化界面管理你的所有项目。

  • CLI 服务

CLI 服务 (@vue/cli-service) 是一个开发环境依赖。它是一个 npm 包,局部安装在每个 @vue/cli 创建的项目中。

CLI 服务是构建于 webpack 和 webpack-dev-server 之上的。它包含了:

* 加载其它 CLI 插件的核心服务;
* 一个针对绝大部分应用优化过的内部的 webpack 配置;
* 项目内部的 vue-cli-service 命令,提供 serve、build 和 inspect 命令。

如果你熟悉 create-react-app 的话,@vue/cli-service 实际上大致等价于 react-scripts,尽管功能集合不一样。

  • CLI 插件

CLI 插件是向你的 Vue 项目提供可选功能的 npm 包,例如 Babel/TypeScript 转译、ESLint 集成、单元测试和 end-to-end 测试等。Vue CLI 插件的名字以 @vue/cli-plugin- (内建插件) 或 vue-cli-plugin- (社区插件) 开头,非常容易使用。

当你在项目内部运行 vue-cli-service 命令时,它会自动解析并加载 package.json 中列出的所有 CLI 插件。

插件可以作为项目创建过程的一部分,或在后期加入到项目中。它们也可以被归成一组可复用的 preset。

Vue CLI安装

Vue CLI 需要 Node.js 8.9 或更高版本 (推荐 8.11.0+)。你可以使用 nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。

1
npm install -g @vue/cli

安装之后,你就可以在命令行中访问 vue 命令。你可以通过简单运行 vue,看看是否展示出了一份所有可用命令的帮助信息,来验证它是否安装成功。

创建项目

运行以下命令来创建一个新项目:

1
vue create hello-world

运行项目

在一个 Vue CLI 项目中,@vue/cli-service 安装了一个名为 vue-cli-service 的命令。你可以在 npm scripts 中以 vue-cli-service、或者从终端中以 ./node_modules/.bin/vue-cli-service 访问这个命令。

这是你使用默认 preset 的项目的 package.json:

1
2
3
4
5
6
{
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
}
}

你可以通过 npm 调用这些 script:

1
npm run serve

参考链接

  1. Vue.js,by wikipedia.
  2. vue cli,by vuejs homepage.

Expressjs框架的安装使用

发表于 2019-07-18 | 更新于 2023-02-03

Express是高度包容、快速而极简的 Node.js Web 框架。下面简单介绍Express框架的安装和使用。

安装

安装最新Nodejs长期支持版

前往nodejs官方网站下载其最新长期支持版,并安装。

安装Express生成器

Express生成器是一个脚手架工具,能够快速生成标准的Express Web框架,简化开发过程。具体安装方法如下:

1
npm install -g express-generator@4

创建APP:

1
$ express /tmp/foo && cd /tmp/foo

安装依赖:

1
npm install

启动Web服务器:

1
2
3
4
# 直接启动
npm start
# 调试启动
SET DEBUG=server:* & npm start

访问网站: http://localhost:3000

express vs koa vs hapi

请参考The Best Node.js Framework: Koa VS Express VS Hapi [Detailed Comparison]。

参考链接

  1. Express,by Express homepage.
  2. Express github,by Express github.
  3. The Best Node.js Framework: Koa VS Express VS Hapi [Detailed Comparison],by Savvycom JSC.

Excel宏编程简易教程

发表于 2019-07-16 | 更新于 2019-07-17

期末了,媳妇计算学生平时成绩好辛苦,于是准备编写Excel宏程序提高媳妇工作的效率,节省时间。于是简单记录Excel宏编程的相关知识。

基本概念

为了编写Excel宏,首先需要了解一些基本概念:

工作簿

工作簿相关概念有:Workbooks、Workbook、ActiveWorkbook、ThisWorkbook。

  • Workbooks集合包含excel中所有当前打开的excel工作簿,亦即所有打开的excel文件;

  • Workbook对应Workbooks中的成员,即其中的excel文件;

  • ActiveWorkbook代表当前处于活动状态的工作簿,即当前显示的excel文件;

  • ThisWorkbook代表其中有Visual Basic代码正在运行的工作簿。

在具体使用中可用Workbooks(index)来引用Workbook对象,其中index为工作簿名称或编号,如Workbooks(1)、 Workbooks(“年度报表.xls”)。而编号按照创建或打开工作簿的顺序来确定,第一个打开的工作簿编号为1,第二个打开的工作簿为2……。

工作表

工作表相关概念有:Worksheets、Worksheet、ActiveSheet。

  • Worksheets集合包含工作簿中所有的工作表,即一个excel文件中的所有数据表页;

  • Worksheet则代表其中的一个工作表;

  • ActiveSheet代表当前处于的活动状态工作表,即当前显示的一个工作表。

图表

图表相关概念有:Chart 、Charts、ChartObject、ChartObjects、ActiveChart。

  • Chart代表工作簿中的图表。该图表既可为嵌入式图表(包含在ChartObject中),也可为一个分开的(单独的)图表工作表。

  • Charts代表指定工作簿或活动工作簿中所有图表工作表的集合,但不包括嵌入式在工作表或对话框编辑表中的图表。使用Charts(index) 可引用单个Chart图表,其中index是该图表工作表的索引号或名称;如Charts(1)、Charts(“销售图表”)。

  • ChartObject代表工作表中的嵌入式图表,其作用是作为Chart对象的容器。利用ChartObject可以控制工作表上嵌入式图表的外观和尺寸。

  • ChartObjects代表指定的图表工作表、对话框编辑表或工作表上所有嵌入式图表的集合。

单元格

单元格相关概念有:Cells、ActiveCell、Range、Areas。

  • Cells(row,column)代表单个单元格,其中row为行号,column为列号。如可以用Cells(1,1)、Cells(10,4)来引用”A1”、”D10” 单元格。

  • ActiveCell代表活动工作表的活动单元格,或指定工作表的活动单元格。

  • Range代表工作表中的某一单元格、某一行、某一列、某一选定区域(该选定区域可包含一个或若干连续单元格区域)或者某一三维区域。可用Range(arg)来引用单元格或单元格区域,其中arg可为单元格号、单元格号范围、单元格区域名称。如Range(“A5”)、 Range(“A1:H8”)、Range(“Criteria”)。虽然可用Range(“A1”)返回单元格A1,但用Cells更方便,因为此时可 用变量指定行和列。

  • Areas 为选定区域内的连续单元格块的集合,其成员是Range对象。

行与列

行与列相关概念有:Rows、Columns、Row、Column。

Rows、Columns分别代表活动工作表、单元格区域范围Range、指定工作表中的所有行数、列数。

基本语法

Visual Basic for Applications(VBA)是一种Visual Basic的一种宏语言,主要能用来扩展Windows的应用程序功能,特别是Microsoft Office软件。也可说是一种应用程序视觉化的Basic Sc​​ript。 1994年发行的Excel 5.0版本中,即具备了VBA的宏功能。Excel宏编程主要使用VBA。

数据类型

基本数据类型

即Primary Type Data,下述列表的括号内为字节数:

  • Byte (1):无符号类型,取值范围0-255
  • Boolean (2)
  • Integer (2)
  • Long (4)
  • Single (4)
  • Double (8)
  • Currency (8)
  • Decimal (14)
  • Date (8)
  • String
  • Object (4)
  • Variant (根据分配确定)

自定义的数据类型

相当于C语言的struct,例如:

1
2
3
4
5
Type 自定义类型名
元素名 As 类型
…
[元素名 As 类型]
End Type

数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Option Base 0 '數組索引值從0開始
Option Base 1 '數組索引值從1開始
Dim MyArray(10) '聲明一個數組變量,10是最大的可用的數組索引值
MyArray(5) = 101 '給數組的元素賦值
Dim Data(10,5) '聲明一個二維數組變量
Data(1,1) = "A001" '給數組元素賦值
Dim cArr(-11 To 20, 1 To 3) As String '聲明一個數組,定義數組索引值的上下界
Dim dArr() As String '聲明動態數組
ReDim dArr(0 To 5, 1 To 2) '改變動態數組的尺寸默認把原數據清除。如果保留原來的數據,必須加上參數Preserve。
'使用Preserve參數時只能改變最後一維的大小
If UBound(vTemp) = -1 Then
'判斷數組變量vTemp是否為 空數組
End If
Erase MyArrar, Data 'Eras​​e語句清除數組元素,釋放變量佔用的空間

常量

日期常量由符号“#”将字符括起来,如#2012-1-1#。

系统定义常量有3个:True、False和Null。

固有常量是编程时引用的对象库定义的常量。所有固有常量都可以在宏或VBA代码中使用。通常,固有常量通过前两个字母来指明定义该常量。来自VB库的常量则以“vb”开头。来自Access的常量以“ac”开头。可以使用对象浏览器来查看所有对象库中的固有常量列表。

可以自行定义常量。如:

1
Global Const 符号常量名称 = 常量值

控制结构

if 语句

1
2
3
4
5
6
7
8
9
if 條件1 then
語句1
elseif 條件2 then
語句2
elseif ...
...
else
語句n
end if

Select Case 语句

1
2
3
4
5
6
7
8
9
Select Case 表達式
Case 表達式列表1
語句1
Case 表達式列表2
語句2
...
Case 表達式列表n
語句n
End Select

Do…Loop 语句

1
2
3
4
5
Do While或Until 條件
語句塊1
Exit Do
語句塊2
Loop
1
2
3
4
5
Do
語句塊1
Exit Do
語句塊2
Loop While或Until 條件

For…Next语句

1
2
3
For 循環控制變量=初值To 終值Step 步長
語句塊 ‘Exit For語句可以跳出循環體
Next

For Each … Next语句

1
2
3
4
For Each 循環控制變量 In 集合變量
語句塊
Exit For語句可以跳出循環體
Next 循環控制變量

跳出本次循环的continue语句

VBA没有类似C语言的continue语句。通常可如此写程序:

1
2
3
4
5
6
7
For 循環控制變量=初值 To 終值 Step 步長
Do '用于模拟continue
語句塊
If 条件 Then Exit Do '用于模拟continue
語句塊
Loop While False '用于模拟continue
Next

With语句

1
2
3
With 對象引用
語句塊
End With

On Error语句

1
On Error Goto 出錯處理語句的label '跳轉到出錯處理語句

或者

1
On Error Resume Next '遇到錯誤,不管錯誤,繼續往下執行

过程与函数

1
2
3
4
5
Sub 過程名(參數表)
語句塊
Exit Sub
語句塊
End Sub
1
2
3
4
5
Function 函數名(參數表) As Type
語句塊
函數名=表達式
Exit Function
End Function

常用内置函数

VBA的常用内置函数列表:

  • MsgBox
  • InputBox
  • 舍入函数:Fix 向0取整,Int向下取整, Round四舍五入
  • Rnd 返回0-1内的单精度随机数
  • 字符串函数:
    • Filter:对字符串的一维数组的过滤
    • InStr([Start, ],[, Compare])与InStrRev: 查找子串
    • Len 字符串长度
    • Join:连接一维数组中的所有子字符串
    • Left,Right,Mid 截取子字符串
    • Space(数值) 生成空格字符串
    • Ucase,Lcase 大小写转换函数
    • Ltrim, Rtrim,Trim 删除首尾空格
    • Replace
    • Split:分割一个字符串成为一维数组
    • StrComp:字符串比较
    • StrConv:字符串转换
    • String(number, character):制定字符重复若干次
    • StrReverse
  • 日期/时间有关函数:
    • Year, Month, Day, WeekDay,Hour,Minute,Second 截取日期时间分量
    • DateAdd 日期/时间增量函数
    • DateDiff(<间隔类型>,<日期1>,<日期2>[,W1][,W2])日期/时间的距离函数
    • DatePart(<分割类型>,<日期>[,w1][,w2])时间分割函数
    • DateSerial(<表达式1>,<表达式2>,<表达式3>) 合成日期;DateValue(“字符串表达式”)返回日期;
    • Date,Time,Now,Timer 返回日期时间
    • DateValue
    • TimeSerial:由时间序列得到时间对象
    • TimeValue:由时间字符串得到时间对象
    • Weekday:获得日期的周几
    • WeekdayName
  • 转换函数:CBool、CByte、CCur、 CDate、 CDbl、CDec、CInt、 CLng、CLngLng、CLngPtr、CSng、CStr、CVar、CVErr、Asc(<字符串表达式>)返回第一个字符的Ascii编码值、Chr(ASCII码)返回字符、Hex、Oct、Str(<数值表达式>)返回字符串、Val(string)、Format、FormatCurrency、FormatDateTime、FormatNumber、FormatPercent、MonthName
  • Nz(表达式或字段属性值[,规定值])如果是空,则返回0或者””或者函数的第二个参数值
  • 验证函数:isNumeric、isDate、isNull、isEmpty IsArray、IsError、IsMissing、IsObject
  • 数学函数:Abs、Sqr、Tan、Atn(即atan)、Sin、Cos、Exp(e为基的指数)、Log自然对数
  • Array:构造一个Array对象
  • CallByName: get or set a property, or invoke a method at run time using a string name.
  • 控制流:Choose:类似于C语言的select语句、IIf相当于IF-ELSE语句、Switch
  • Command:获取命令行参数
  • CreateObject:创建ActiveX对象
  • CurDir:返回指定驱动器的当前工作路径
  • 由基本数学函数导出的函数:Sec、Cosec、Cotangent、Cotan、Arcsin、Arccos、Arcsec、Arccosec、Arccotan、HSin、HCos、HTan、HSec、HCosec、HCotan、HArcsin、HArccos、HArctan、HArcsec、HArccosec、HArccotan、LogN
  • DoEvents:暂时把CPU控制权交回给系统。
  • Environ:返回环境变量的值
  • 文件操作:
    • Dir:返回满足条件的所有文件、目录的名字
    • EOF
    • FileAttr
    • FileDateTime
    • FileLen
    • FreeFile Function
    • GetAttr:返回文件、目录的属性值
    • Input:读取文件
    • Loc:文件指针位置
    • LOF:文件打开时的指针位置
    • Seek:文件指针定位
    • Spc:使用Print做position output
    • Tab:用于Print函数
    • Error:错误号对应的错误消息
    • Windows Registry中的数据:GetAllSettings、SaveSetting、DeleteSetting、GetSetting
    • GetObject:ActiveX组建的引用
    • IMEStatus:返回当前Input Method Editor (IME)。
    • Macintosh平台:MacID、MacScript
  • 金融函数:
    • DDB:使用double-declining balance计算贬值
    • FV:计算固定利率的年金
    • IPmt:计算利率
    • IRR:计算利率
    • MIRR:计算利率
    • NPer:计算周期数
    • NPV:计算net present value
    • Pmt:计算支付数
    • PPmt:计算本金支付数
    • PV:计算present value
    • Rate:利息率
    • SLN:straight-line depreciation
    • SYD:计算sum-of-years’ digits depreciation
  • Partition:返回字符串,表示一个数值名字落在各个range内。常用于SQL select语句
  • QBColor:颜色值
  • RGB:颜色值
  • TypeName:得到变量的类型名
  • VarType:得到变量的类型数

表达式

比较特殊的运算符有指数运算^,浮点除法/,整数除法\,取模运算Mod,不等逻辑比较运算<>

简单示例

在Excel开发工具中点击录制宏,生成一个VBA过程,创建如下代码计算学生平均成绩:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Sub 计算平均成绩()
'
' 计算平均成绩 宏
' 计算平均成绩
'
' 快捷键: Ctrl+l
'
Application.Goto Reference:="计算平均成绩"

Dim count As Integer ' 统计学生总数
count = Range("A1").CurrentRegion.Rows.count ' 统计学生总数

ActiveSheet.Cells(1, "E").Value = "平均成绩"
Dim workSocre As Double ' 课程分
Dim videoScore As Double ' 视频分
Dim discussScore As Double ' 讨论分

For i = 2 To count
' 计算学生平均成绩
workSocre = ActiveSheet.Cells(i, "A").Value
videoScore = ActiveSheet.Cells(i, "B").Value
discussScore = Discuss(ActiveSheet.Cells(i, "C").Value)
ActiveSheet.Cells(i, "E").Value = workSocre * 0.6 + videoScore * 100 * 0.2 + discussScore * 0.2
Next
MsgBox ("平均成绩计算完成!")
End Sub


Function Discuss(discussCount As Integer) As Integer
Dim score As Integer
Select Case discussCount
Case Is >= 20
score = 100
Case Is >= 15
score = 80
Case Is >= 10
score = 60
Case Is >= 5
score = 40
Case Is > 0
score = 20
Case Is = 0
score = 0
End Select
Discuss = score
End Function

参考链接

  1. Excel宏教程 (宏的介绍与基本使用),by 远洪.
  2. Visual Basic for Applications,by wikipedia.
  3. VBA——Range操作,by 风之工程师.

小波变换学习笔记

发表于 2019-07-14 | 更新于 2019-10-04

小波分析(英语:wavelet analysis)或小波变换(英语:wavelet transform)是指用有限长或快速衰减的“母小波”(mother wavelet)的振荡波形来表示信号。该波形被缩放和平移以匹配输入的信号。

小波变化的发展,承袭Gabor transform的局部化思想,并且克服了傅里叶和Gabor transform的部分缺陷,小波变换提供了一个可以调变的时频窗口,窗口的宽度(width)随着频率变化,频率增高时,时间窗口的宽度就会变窄,以提高分辨率.小波在整个时间范围内的振幅平均值为0,具有有限的持续时间和突变的频率与震幅,可以是不规则,或不对称的信号。

小波变换分成两个大类:离散小波变换(DWT) 和连续小波变换(CWT)。两者的主要区别在于,连续变换在所有可能的缩放和平移上操作,而离散变换采用所有缩放和平移值的特定子集。

参考链接

  1. 能不能通俗的讲解下傅立叶分析和小波分析之间的关系?,by zhihu.
  2. 什么是线性平稳信号和非线性非平稳信号?,by zhihu.
  3. 形象易懂讲解算法I——小波变换,by 咚懂咚懂咚.
  4. 从傅里叶变换进阶到小波变换(一),by 1335.
  5. 信号频域分析方法的理解(频谱、能量谱、功率谱、倒频谱、小波分析),by Mr.括号.
  6. 小波分析,by wikipedia.
  7. 傅里叶变换交互式入门,by Jez Swanson.
上一页1…373839…53下一页

Jack Huang

521 日志
67 标签
© 2025 Jack Huang
由 Hexo 强力驱动
|
主题 — NexT.Muse