使用SourceTree 3.3.8
,在检出版本库的时候,选择记住密码。过一段时间之后,版本库的密码修改之后,提示access denied
。
解决方法为删除已经记住的用户名密码,如下:
1 |
del "C:\Users\%username%\AppData\Local\Atlassian\SourceTree\passwd" |
具体文件位置如下图:
使用SourceTree 3.3.8
,在检出版本库的时候,选择记住密码。过一段时间之后,版本库的密码修改之后,提示access denied
。
解决方法为删除已经记住的用户名密码,如下:
1 |
del "C:\Users\%username%\AppData\Local\Atlassian\SourceTree\passwd" |
具体文件位置如下图:
最近在使用brew
升级git
的时候,报告如下错误:
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
$ brew install git -s -d -v --env=std Warning: You are using macOS 10.11. We (and Apple) do not provide support for this old version. You will encounter build failures with some formulae. Please create pull requests instead of asking for help on Homebrew's GitHub, Discourse, Twitter or IRC. You are responsible for resolving any issues you experience while you are running this old version. Updating Homebrew... ==> Downloading https://www.kernel.org/pub/software/scm/git/git-htmldocs-2.27.0. curl: (60) SSL certificate problem: Invalid certificate chain More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option. Error: Failed to download resource "git--html" Download failed: https://www.kernel.org/pub/software/scm/git/git-htmldocs-2.27.0.tar.xz ==> Auto-updated Homebrew! Updated 1 tap (homebrew/cask). ==> Updated Casks balenaetcher gzdoom poi strawberry cabal hstracker stella trilium-notes Warning: You are using macOS 10.11. We (and Apple) do not provide support for this old version. You will encounter build failures with some formulae. Please create pull requests instead of asking for help on Homebrew's GitHub, Discourse, Twitter or IRC. You are responsible for resolving any issues you experience while you are running this old version. /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/gettext.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/pcre2.rb /usr/bin/curl --disable --globoff --show-error --user-agent Homebrew/2.3.0\ \(Macintosh\;\ Intel\ Mac\ OS\ X\ 10.11.6\)\ curl/7.43.0 --retry 3 --location --silent --head --request GET https://www.kernel.org/pub/software/scm/git/git-htmldocs-2.27.0.tar.xz ==> Downloading https://www.kernel.org/pub/software/scm/git/git-htmldocs-2.27.0.tar.xz /usr/bin/curl --disable --globoff --show-error --user-agent Homebrew/2.3.0\ \(Macintosh\;\ Intel\ Mac\ OS\ X\ 10.11.6\)\ curl/7.43.0 --retry 3 --location --range 0-1 --dump-header - --write-out \%\{http_code\} --output /dev/null https://www.kernel.org/pub/software/scm/git/git-htmldocs-2.27.0.tar.xz /usr/bin/curl --disable --globoff --show-error --user-agent Homebrew/2.3.0\ \(Macintosh\;\ Intel\ Mac\ OS\ X\ 10.11.6\)\ curl/7.43.0 --fail --retry 3 --location --remote-time --continue-at 0 --output /Users/xxxx/Library/Caches/Homebrew/downloads/af92f79273b58e47216b46d936335255b08e1eb74369b4714bac1c0e0650b50e--git-htmldocs-2.27.0.tar.xz.incomplete https://www.kernel.org/pub/software/scm/git/git-htmldocs-2.27.0.tar.xz curl: (60) SSL certificate problem: Invalid certificate chain More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option. Error: Failed to download resource "git--html" Download failed: https://www.kernel.org/pub/software/scm/git/git-htmldocs-2.27.0.tar.xz /usr/local/Homebrew/Library/Homebrew/download_strategy.rb:312:in `rescue in fetch' /usr/local/Homebrew/Library/Homebrew/download_strategy.rb:309:in `fetch' /usr/local/Homebrew/Library/Homebrew/resource.rb:131:in `fetch' /usr/local/Homebrew/Library/Homebrew/formula_installer.rb:988:in `each' /usr/local/Homebrew/Library/Homebrew/formula_installer.rb:988:in `fetch' /usr/local/Homebrew/Library/Homebrew/cmd/install.rb:329:in `install_formula' /usr/local/Homebrew/Library/Homebrew/cmd/install.rb:261:in `block in install' /usr/local/Homebrew/Library/Homebrew/cmd/install.rb:259:in `each' /usr/local/Homebrew/Library/Homebrew/cmd/install.rb:259:in `install' /usr/local/Homebrew/Library/Homebrew/brew.rb:110:in `<main>' |
手工去下载数据,看到更具体的错误信息,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ curl https://www.kernel.org/pub/software/scm/git/git-htmldocs-2.27.0.tar.xz curl: (60) SSL certificate problem: Invalid certificate chain More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option |
解决方法为暂时要求curl
忽略证书错误问题,如下:
1 2 3 4 |
$ touch ~/.curlrc # 增加禁止校验的参数 $ echo --insecure >> ~/.curlrc |
注意,上述配置之后,可能会出现类似如下错误:
1 |
curl: (22) The requested URL returned error: 403 [[[!!! BREAKING CHANGE !!!]]] Support for clients that do not support Server Name Indication is temporarily disabled and will be permanently deprecated soon. See https://status.python.org/incidents/hzmjhqsdjqgb and ht |
How to fix curl: (60) SSL certificate: Invalid certificate chain
第一种(字符串模板写法):
直接写在vue构造器里,这种写法比较直观,适用于html代码不多的场景,但是如果模板里html代码太多,不便于维护,不建议这么写.
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 |
<!DOCTYPE html> <html> <!-- WARNING! Make sure that you match all Quasar related tags to the same version! (Below it's "@1.7.4") --> <head> <!-- <link href="https://cdn.jsdelivr.net/npm/quasar@1.7.4/dist/quasar.min.css" rel="stylesheet" type="text/css"> --> <link href="https://www.mobibrw.com/wp-content/uploads/2020/06/quasar@1.7.4.css" rel="stylesheet" type="text/css"> </head> <body> <div id="q-app"> </div> <!-- Add the following at the end of your body tag --> <!-- <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/quasar@1.7.4/dist/quasar.umd.min.js"></script> --> <script src="https://www.mobibrw.com/wp-content/uploads/2020/06/vue@2.0.0.js"></script> <script src="https://www.mobibrw.com/wp-content/uploads/2020/06/quasar.umd@1.7.4.js"></script> <script> /* Example kicking off the UI. Obviously, adapt this to your specific needs. Assumes you have a <div id="q-app"></div> in your <body> above */ new Vue({ el: '#q-app', data: function () { return { version: Quasar.version } }, template: `<div class="q-ma-md"> Running Quasar v{{ version }}</div>` // ...etc }) </script> </body> </html> |
第二种:
直接写在template标签里,这种写法跟写html很像。
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 47 48 49 |
<!DOCTYPE html> <html> <!-- WARNING! Make sure that you match all Quasar related tags to the same version! (Below it's "@1.7.4") --> <head> <!-- <link href="https://cdn.jsdelivr.net/npm/quasar@1.7.4/dist/quasar.min.css" rel="stylesheet" type="text/css"> --> <link href="https://www.mobibrw.com/wp-content/uploads/2020/06/quasar@1.7.4.css" rel="stylesheet" type="text/css"> </head> <body> <div id="q-app"> <template id='template1'> <div class="q-ma-md"> Running Quasar v{{ version }} </div> </template> </div> <!-- Add the following at the end of your body tag --> <!-- <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/quasar@1.7.4/dist/quasar.umd.min.js"></script> --> <script src="https://www.mobibrw.com/wp-content/uploads/2020/06/vue@2.0.0.js"></script> <script src="https://www.mobibrw.com/wp-content/uploads/2020/06/quasar.umd@1.7.4.js"></script> <script> /* Example kicking off the UI. Obviously, adapt this to your specific needs. Assumes you have a <div id="q-app"></div> in your <body> above */ new Vue({ el: '#q-app', data: function () { return { version: Quasar.version } }, template: '#template1' // ...etc }) </script> </body> </html> |
第三种:
写在script标签里,这种写法官方推荐,vue官方推荐script中type属性加上"x-template",即:
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 47 48 49 |
<!DOCTYPE html> <html> <!-- WARNING! Make sure that you match all Quasar related tags to the same version! (Below it's "@1.7.4") --> <head> <!-- <link href="https://cdn.jsdelivr.net/npm/quasar@1.7.4/dist/quasar.min.css" rel="stylesheet" type="text/css"> --> <link href="https://www.mobibrw.com/wp-content/uploads/2020/06/quasar@1.7.4.css" rel="stylesheet" type="text/css"> </head> <body> <div id="q-app"></div> <script type="x-template" id="template1"> <div class="q-ma-md"> Running Quasar v{{ version }} </div> </script> <!-- Add the following at the end of your body tag --> <!-- <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/quasar@1.7.4/dist/quasar.umd.min.js"></script> --> <script src="https://www.mobibrw.com/wp-content/uploads/2020/06/vue@2.0.0.js"></script> <script src="https://www.mobibrw.com/wp-content/uploads/2020/06/quasar.umd@1.7.4.js"></script> <script> /* Example kicking off the UI. Obviously, adapt this to your specific needs. Assumes you have a <div id="q-app"></div> in your <body> above */ new Vue({ el: '#q-app', data: function () { return { version: Quasar.version } }, template: '#template1' // ...etc }) </script> </body> </html> |
推荐这个写法的主要原因就可以把模版文件写到另外的一个JS文件里面,然后动态加载,实现模版复用以及文件分离。不至于一个页面里面实现太多的东西,导致页面代码混乱。
Vue 是一个轻巧、高性能、可组件化的MVVM库,API简洁明了,上手快。从Vue推出以来,得到众多Web开发者的认可。
在公司的Web前端项目开发中,多个项目采用基于Vue的UI组件框架开发,并投入正式使用。
开发团队在使用Vue.js框架和UI组件库以后,开发效率大大提高,自己写的代码也少了,很多界面效果组件已经封装好了。
在选择Vue UI组件库的过程中,通过GitHub上根据star数量、文档丰富程度、更新的频率以及维护等因素,也收集整理了一些优秀的Vue UI组件库。
PS:国内的UI组件大部分都只有一部分的,常用的头部导航,底部导航,listview,grid表格很多都是没有的。
后面才发现,基于Vue的Quasar Framework 介绍 这个框架UI组件很全面,准备下次使用这个框架了
基于Vue的Quasar Framework 中文网
http://www.quasarchs.com/
quasarframework/quasar: Quasar Framework
https://github.com/quasarframework/quasar
Quasar(发音为/kweɪ.zɑɹ/)是MIT许可的开源框架(基于Vue),可帮助Web开发人员创建:
响应式网站
PWA(Progressive Web App)
通过Apache Cordova构建移动APP(Android,iOS,…)
多平台桌面应用程序(使用Electron)
Quasar允许开发人员编写一次代码,然后使用相同的代码库同时部署为网站、PWA、Mobile App和Electron App。使用最先进的CLI设计应用程序,并提供精心编写,速度非常快的Quasar Web组件。
当使用Quasar时,你不需要像Hammerjs,Momentjs或Bootstrap这样的额外重型库。它拥有这些功能,而且体积很小!
==============
1、 iView UI组件库
iView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品。iView的组件还是比较齐全的,更新也很快,文档写得很详细。有公司团队维护,比较可靠的Vue UI组件框架。iView生态也做得很好,还有开源了一个iView Admin,做后台非常方便。官网上介绍,iView已经应用在TalkingData、阿里巴巴、百度、腾讯、今日头条、京东、滴滴出行、美团、新浪、联想等大型公司的产品中。
iView官网:https://www.iviewui.com/
2、Vux UI组件库
Vux是基于WeUI和Vue2.x开发的移动端UI组件库,主要服务于微信页面。Vux的定位已经很明确了,一是:Vue移动端UI组件库,二是:WeUI的基础样式库。Vux的组件涵盖了所有的WeUI的内容,还扩展了一些常用的组件。比如:Sticky、timeline、v-chart、XCircle。Vux是个人维护的。但是GitHub上star还是很高的,达到13k。在GitHub上看到对issue的关闭还是很迅速的。Vux文档基本的组件用法和效果都讲解到位了。在vux官网上也展示了很多Vux的使用案例。在微信页面开发中,基本没有太多的bug,开发还是比较顺手的。
Vux官网:https://vux.li/
3、Element UI组件库
Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。Element是饿了么前端开源维护的Vue UI组件库,更新频率还是很高的,基本一周到半个月都会发布一个新版本。组件齐全,基本涵盖后台所需的所有组件,文档讲解详细,例子也很丰富。没有实际使用过,网上的Element教程和文章比较多。Element应该是一个质量比较高的Vue UI组件库。
Element官网:http://element.eleme.io/#/zh-CN
4、Mint UI组件库
Mint UI基于 Vue.js 的移动端组件库,同样出自饿了么前端的项目。Mint UI是真正意义上的按需加载组件。可以只加载声明过的组件及其样式文件。Mint UI 采用 CSS3 处理各种动效,避免浏览器进行不必要的重绘和重排,从而使用户获得流畅顺滑的体验。网上的视频教程很多都是基于Mint UI来讲的,开发移动端web项目还是很方便,文档也很简介明了。很多页面Mint UI组件都已经封装好,基本可以照着例子写,简单的调整一下就可以实现。不过,在GitHub上看最后一次代码提交在2018年1月16日。不知道是项目比较稳定没有更新,还是项目有被废弃的可能。
Mint UI官网:http://mint-ui.github.io/#!/zh-cn
5、Bootstrap-Vue UI组件库
Bootstrap-VUE提供了基于vue2的Bootstrap V4组件和网格系统的实现,完成了广泛和自动化的WAI ARA可访问性标记。Bootstrap 4是最新发布的版本,与 Bootstrap3 相比拥有了更多的具体的类以及把一些有关的部分变成了相关的组件。同时 Bootstrap.min.css 的体积减少了40%以上。Bootstrap4 放弃了对 IE8 以及 iOS 6 的支持,现在仅仅支持 IE9 以上 以及 iOS 7 以上版本的浏览器。想当初刚流行响应式网站的时候,Bootstrap是世界上最受欢迎的建立移动优先网站的框架,Bootstrap可以说风靡全球。就算放在现在很多企业网站都是采用Bootstrap做的响应式。Bootstrap-Vue可以让你在Vue中也实现Bootstrap的效果。
Bootstrap-Vue官网:https://bootstrap-vue.js.org/
6、Ant Design Vue UI组件库
Ant Design Vue是 Ant Design 3.X 的 Vue 实现,开发和服务于企业级后台产品。在GitHub上可以找到几个Ant Design的Vue组件。不过相比较而言,Ant Design Vue更胜一筹。Ant Design Vue共享Ant Design of React设计工具体系,实现了所有Ant Design of React的组件,支持现代浏览器和 IE9 及以上(需要 polyfills)。可以让熟悉Ant Design的在使用Vue时,很容易的上手。
Ant Design Vue官网:https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/
7、AT-UI UI组件库
AT-UI 是一款基于 Vue.js 2.0 的前端 UI 组件库,主要用于快速开发 PC 网站中后台产品,支持现代浏览器和 IE9 及以上。AT-UI 更加精简,实现了后台常用的组件。
AT_UI官网:https://at-ui.github.io/at-ui/#/zh
8、Vant UI组件库
Vant是一个轻量、可靠的移动端 Vue 组件库。Vant是有赞团队开源的,主要维护也是有赞团队。Vant Weapp 是有赞移动端组件库 Vant 的小程序版本,两者基于相同的视觉规范,提供一致的 API 接口,助力开发者快速搭建小程序应用。截止到目前,Vant已经开源了50+ 个经过有赞线上业务检验的组件。比如:、AddressEdit 地址编辑、AddressList 地址列表、Area 省市区选择、Card 卡片、Contact 联系人、Coupon 优惠券、GoodsAction 商品页行动点、SubmitBar 提交订单栏、Sku 商品规格弹层。如果做商城的,不太在意界面,实现业务逻辑的话,用Vant组件库开发还是很快的。
Vant官网:https://youzan.github.io/vant/#/zh-CN/intro
9、cube-ui UI组件库
cube-ui 是基于 Vue.js 实现的精致移动端组件库。由滴滴内部组件库精简提炼而来,经历了业务一年多的考验,并且每个组件都有充分单元测试,为后续集成提供保障。在交互体验方面追求极致。遵循统一的设计交互标准,高度还原设计效果;接口标准化,统一规范使用方式,开发更加简单高效。支持按需引入和后编译,轻量灵活;扩展性强,可以方便地基于现有组件实现二次开发。
cube-ui官网:https://didi.github.io/cube-ui/#/zh-CN
10、Muse-UI UI组件库
Muse-UI基于 Vue 2.0 优雅的 Material Design UI 组件库。Muse UI 拥有40多个UI 组件,用于适应不同业务环境。Muse UI 仅需少量代码即可完成主题样式替换。Muse UI 可用于开发的复杂单页应用
Muse-UI官网:https://muse-ui.org/#/zh-CN
11、N3-components UI组件库
N3组件库是基于Vue.js构建的,让前端工程师和全栈工程师能快速构建页面和应用。N3-components超过60个组件 组件列表、自定义样式、支持多种模化范式(UMD)、使用ES6进行开发。
N3官网:https://n3-components.github.io/N3-components/component.html
12、Mand Mobile
Mand Mobile是面向金融场景的Vue移动端UI组件库,丰富、灵活、实用,快速搭建优质的金融类产品,让复杂的金融场景变简单。Mand Mobile含有丰富的组件30+的基础组件,覆盖金融场景,极高的易用性组件均有详细说明文档、案例演示,汲取最前沿技术,组件化轻量化实现,兼顾稳定和品质,努力实现金融场景的全覆盖。
Mand Mobile官网:https://didi.github.io/mand-mobile/#/zh-CN/home
下面是1.x的文档和演示地址:(文档地址已经迁移了)
https://mand-mobile.github.io/1x-doc/
https://mand-mobile.github.io/2x-doc/
之前的地址打不开了
13、we-vue UI组件库
we-vue 是一套基于 Vue.js 的移动关组件库,结合 weui.css 样式库,封装了一系列组件,非常适于微信公众号等移动端开发。we-vue 包含35+ 个组件,单元测试覆盖率超 98%,支持 babel-plugin-import,完善的在线文档,详细的在线示例。
we-vue官网:https://wevue.org/
14、veui UI组件库
veui是一个由百度EFE team开发的Vue企业级UI组件库。目前文档还没有,只有demo。
GitHub上说是正在进行的一项工作。那我们就耐心等待吧。
veui官网:https://ecomfe.github.io/veui/components/#/
15、Semantic-UI-Vue UI组件库
Semantic-UI-Vue是基于 Vue.js对Semantic-UI 框架的实现。
Semantic作为一款开发框架,帮助开发者使用对人类友好的HTML语言构建优雅的响应式布局。Semantic-UI-Vue提供了一个类似于 Semantic-UI 的 API 以及一组可定制的主题。
Semantic-UI-Vue官网:https://semantic-ui-vue.github.io/#/
在选择框架的时候一定要根据实际Web开发情况和团队的熟悉程度来选择。一个好的UI组件库对一个Web项目来说很重要
16.Vue.js Material Component Framework — Vuetify.js
Vuetify完全根据Material Design规范开发。每个组件都是手工制作的,为您的下一个伟大的应用程序带来最好的UI工具。开发并没有停留在Google规范中的核心组件上。通过社区成员和赞助商的支持,更多的组件将被设计并提供给大家享受。
这个主要是国外比较流行的vue ui组件,各种功能都有,有中文翻译的,但有些还是英文的,翻译得不是很好
PS:国内的UI组件大部分都只有一部分的,常用的头部导航,底部导航,listview,grid表格很多都是没有的。
昨天,编程读取XML的时候,遇上了类似下面的一段XML
1 2 3 |
<a:root xmlns:a="http://ww.abc.com/"> <a:book>aaaa</a:book> </a:root> |
起初没有特别的留意,于是乎就像平时读取XML一样使用了。
1 |
var ele = from item in xDoc.Descendants("a:book") select item; |
但是,运行报错,不允许传入冒号:之类的字符,后来查阅资料发现,节点中,冒号前的a代表是的命名空间,冒号后的才是根节点名称。在Root节点中,也对命名空间进行了声明 xmlns:a="http://ww.abc.com/" ,知道了这么一回事后,再来看看如何去读取,正确的读取是:
1 2 3 4 |
XDocument xDoc = XDocument.Load("a.xml"); XNamespace n = @"http://www.abc.com"; var ele = from item in xDoc.Descendants(n + "book") select item.Value; |
从代码可以看出,我声明了一个XNamespace类型的变量,并且把XML文件中出现的命名空间 http://ww.abc.com/ 赋值给它,然后再读取节点的时候,与真正的节点名称book进行拼接就可以了!
XML中出现命名空间的原因是,当你需要使用多个XML一起工作时,由于两个文档都包含带有不同内容和定义的节点元素,就会发生命名冲突,加上命名空间使用可以避免发生冲突,这与C#编程中类的命名空间的用处差不多。
另外,如果需要了解更多操作XML的可以访问下面这篇文章,写得很详细:
http://www.cnblogs.com/nsky/archive/2013/03/05/2944725.html
1.打开项目的时候,选择打开目录 "Open folder...", 这样可以在项目目录下生成 ".vscode" 目录,如下图:
python通用测试框架大多数人用的是unittest+HTMLTestRunner,这段时间看到了pytest文档,发现这个框架和丰富的plugins很好用,所以来学习下pytest.
1 2 3 4 5 6 7 8 9 |
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); Date date = sdf.parse(yourdate); Calendar cal=Calendar.getInstance(); if(null!=date) { cal.setTime(date); if (Calendar.AM == cal.get(Calendar.AM_PM)) { return "上午"; } } |
利用python获取excel中所有下拉选(drop down)中的值,在百度搜了一下午,都没找到合适的方法,还是google靠谱给力,很快就找到解决办法了,分享一下,供有需要的同行参考。
Python使用openpyxl-3.0.3复制Excel的一行内容并且插入到下一行,包含公式,下拉框,示例代码如下:
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# coding=utf-8 # openpyxl-3.0.3 from openpyxl.reader.excel import load_workbook from openpyxl.cell.cell import TYPE_FORMULA from openpyxl.worksheet.worksheet import Worksheet from openpyxl.utils import get_column_letter from openpyxl.worksheet.cell_range import CellRange import re import copy def insert_rows(self, row_idx, cnt, above=False, copy_style=True, copy_merged_columns=True, fill_formulae=True): """Inserts new (empty) rows into worksheet at specified row index. :param row_idx: Row index specifying where to insert new rows. :param cnt: Number of rows to insert. :param above: Set True to insert rows above specified row index. :param copy_style: Set True if new rows should copy style of immediately above row. :param fill_formulae: Set True if new rows should take on formula from immediately above row, filled with references new to rows. Usage: * insert_rows(2, 10, above=True, copy_style=False) """ CELL_RE = re.compile("(?P<col>\$?[A-Z]+)(?P<row>\$?\d+)") row_idx = row_idx - 1 if above else row_idx def replace(m): row = m.group('row') prefix = "$" if row.find("$") != -1 else "" row = int(row.replace("$", "")) row += cnt if row > row_idx else 0 return m.group('col') + prefix + str(row) # First, we shift all cells down cnt rows... old_cells = set() old_fas = set() new_cells = dict() new_fas = dict() for c in self._cells.values(): old_coor = c.coordinate # Shift all references to anything below row_idx if c.data_type == TYPE_FORMULA: c.value = CELL_RE.sub( replace, c.value ) # Here, we need to properly update the formula references to reflect new row indices if old_coor in self.formula_attributes and 'ref' in self.formula_attributes[old_coor]: self.formula_attributes[old_coor]['ref'] = CELL_RE.sub( replace, self.formula_attributes[old_coor]['ref'] ) # Do the magic to set up our actual shift if c.row > row_idx: old_coor = c.coordinate old_cells.add((c.row, c.column)) c.row += cnt new_cells[(c.row, c.column)] = c if old_coor in self.formula_attributes: old_fas.add(old_coor) fa = copy.copy(self.formula_attributes[old_coor]) new_fas[c.coordinate] = fa for coor in old_cells: del self._cells[coor] self._cells.update(new_cells) for fa in old_fas: del self.formula_attributes[fa] self.formula_attributes.update(new_fas) # Next, we need to shift all the Row Dimensions below our new rows down by cnt... # CHANGED: for row in range(len(self.row_dimensions) - 1 + cnt, row_idx + cnt, -1): for row in range(list(self.row_dimensions)[-1] + cnt, row_idx + cnt, -1): new_rd = copy.copy(self.row_dimensions[row - cnt]) new_rd.index = row self.row_dimensions[row] = new_rd del self.row_dimensions[row - cnt] # Now, create our new rows, with all the pretty cells # CHANGED: row_idx += 1 new_row_idx = row_idx + 1 for row in range(new_row_idx, new_row_idx + cnt): # Create a Row Dimension for our new row new_rd = copy.copy(self.row_dimensions[row-1]) new_rd.index = row self.row_dimensions[row] = new_rd # CHANGED: for col in range(1,self.max_column): for col in range(self.max_column): col = col + 1 cell = self.cell(row=row, column=col) source = self.cell(row=row_idx, column=col) if copy_style: cell.number_format = copy.copy(source.number_format) cell.font = copy.copy(source.font) cell.alignment = copy.copy(source.alignment) cell.border = copy.copy(source.border) cell.fill = copy.copy(source.fill) if fill_formulae and TYPE_FORMULA == source.data_type : s_coor = source.coordinate if s_coor in self.formula_attributes and 'ref' not in self.formula_attributes[s_coor]: fa = copy.copy(self.formula_attributes[s_coor]) self.formula_attributes[cell.coordinate] = fa #print("Copying formula from cell %s%d to %s%d"%(col,row-1,col,row)) cell.value = re.sub( "(\$?[A-Z]{1,3}\$?)%d" % (row_idx), lambda m: m.group(1) + str(row), source.value ) cell.data_type = TYPE_FORMULA # Check for Merged Cell Ranges that need to be expanded to contain new cells for cr in self.merged_cells.ranges: min_col, min_row, max_col, max_row = cr.bounds if min_row <= row_idx and max_row > row_idx: if max_row + cnt >= CellRange.max_row.max: cr.expand(down = CellRange.max_row.max - max_row) else: cr.expand(down = cnt) elif min_row > row_idx: if max_row + cnt >= CellRange.max_row.max: cr.expand(down = CellRange.max_row.max - max_row) else: cr.expand(down = cnt) cr.shrink(top = cnt) # Merge columns of the new rows in the same way row above does if copy_merged_columns: bounds = [] for cr in self.merged_cells.ranges: if cr.max_row == cr.min_row == row_idx: bounds.append((cr.min_col, cr.max_col)) for (min_col, max_col) in bounds: for row in range(new_row_idx, new_row_idx + cnt): newCellRange = get_column_letter(min_col) + str(row) + ":" + get_column_letter(max_col) + str(row) self.merge_cells(newCellRange) # update dataValidation validations = self.data_validations.dataValidation for val in validations: for cr in val.cells: min_col, min_row, max_col, max_row = cr.bounds if min_row <= row_idx and max_row >= row_idx: if max_row + cnt >= CellRange.max_row.max: cr.expand(down = CellRange.max_row.max - max_row) else: cr.expand(down = cnt) elif min_row > row_idx: if max_row + cnt >= CellRange.max_row.max: cr.expand(down = CellRange.max_row.max - max_row) else: cr.expand(down = cnt) cr.shrink(top = cnt) # update conditional_formatting tow steps # first get all conditional_formatting need to update cond_fmts = self.conditional_formatting upd_cfs = [] for cf in cond_fmts: for cr in cf.cells: min_col, min_row, max_col, max_row = cr.bounds if min_row <= row_idx and max_row >= row_idx: upd_cfs.append(cf) break elif min_row > row_idx: upd_cfs.append(cf) break # second update conditional_formatting for cf in upd_cfs: rules = cond_fmts[cf] del cond_fmts[cf.cells] for cr in cf.cells: min_col, min_row, max_col, max_row = cr.bounds if min_row <= row_idx and max_row >= row_idx: if max_row + cnt >= CellRange.max_row.max: cr.expand(down = CellRange.max_row.max - max_row) else: cr.expand(down = cnt) elif min_row > row_idx: if max_row + cnt >= CellRange.max_row.max: cr.expand(down = CellRange.max_row.max - max_row) else: cr.expand(down = cnt) cr.shrink(top = cnt) for r in rules: cond_fmts[cf] = r Worksheet.insert_rows = insert_rows if __name__ == "__main__": # 注意,keep_vba=True打开的Excel文档,保存之后,MS Office 无法打开 wb = load_workbook(filename='example.xlsx', read_only=False, keep_vba=False, data_only=False, keep_links=True) ws = wb.active ws.insert_rows(6, 4, above=True, copy_style=True) wb.save('new_document.xlsx') wb.close() |