整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

后端动态生成word或pdf的几种常见方法

后端动态生成word或pdf的几种常见方法

需求要生成动态生成电子文件以及后面签字,但是又要在小程序里预览效果。


生成word的难点

  1. 文档模式和web模式的差异
    生成word,一开始是通过word模板通过修改变量的方式生成新docx文档后,二次打开导出到pdf。结果导出pdf 看了phpword的源码,就是通过word web版式生成html 后 导出pdf。导致docx 一个效果 pdf一个效果。解决方法,放弃word 转pdf 直接 html 转pdf。
  2. 复选框的实现。
    一般有以下几种方式:
    docx 里 插入图片
    docx 里 插入 emoji表情 ?
    docx 里 插入 字符 □ 前面字符需要字体对应
    html 里写入input checkbox 但是要完整的form,id name 要不重复,一样可能导致pdf 里的复选款 一点全选
    html 里 样式 显示checkbox
  3. 签字的实现
    docx 替换字符站位图片
    html里替换图片标签,
  4. 中文乱码
    word乱码 和pdf 乱码 分别处理方法不一样,word乱码 是系统缺中文字体;pdf乱码还需要看库去处理 word转pdf 用的dom2pdf html转pdf 用snappy。dom2pdf 有个上古类去处理,snappy copy store/simsun.ttc 到 /usr/share/fonts/truetype/ chmod 0755 simsun.ttc
  5. 生成html 快速方法
    http://hiprint.io/
    或者 纯前端手写。

.VueRouter基本概念

Vue-Router是 Vue.js官方的路由插件,让用 Vue.js 构建单页应用变得轻而易举。功能包括:

  • 嵌套路由映射
  • 动态路由选择
  • 模块化、基于组件的路由配置
  • 路由参数、查询、通配符
  • 展示由 Vue.js 的过渡系统提供的过渡效果
  • 细致的导航控制
  • 自动激活 CSS 类的链接
  • HTML5 history 模式或 hash 模式
  • 可定制的滚动行为
  • URL 的正确编码

Vue比较适合单页面的项目,所有的网页的内容都是通过一个Html页面进行切换。在这个Html页面中通过不同的路由来控制不同组件的显示,这个控制就需要Vue-Router来完成。

Vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射(对应联系)起来,访问不同的路径就显示不同的组件。

典型单页面运用


所有内容都在一个Html页面显示,每个标题都是一个组件,点击后在不同组件中进行内容切换,显示不同内容。

Vue-Router目前有两个版本。3.X版本 和 4.X 版本

  • Vue-Router3.X 版本只能结合Vue2使用;
  • Vue-Router4.X 版本只能结合Vue3使用;

Vue-Router的安装

Vue-Router3.X 版本 : npm install vue-router@3

Vue-Router4.X 版本 : npm install vue-router@4

官方文档: https://router.vuejs.org/zh/

如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能:

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

2.实例演示:

  • 创建一个新的项目(本例使用Vue2),具体安装过程见前面笔记(九)

将刚刚创建的项目 vuerouter-demo 拖入 Visual Studio Code 中。目前项目中还没有 Vue-Router 需要进行安装。

注意:本例由于使用的是Vue2,所以要安装vue-router3

在Visual Studio Code 中终端中输入如下命令:

npm install vue-router@3

安装完成后在 package.json 中及可以看到 vue-router3


  • 创建路由组件:

下面模拟网易音乐的界面,在项目components文件夹中自定义Discover.vue、Friends.vue、My.vue三个组件,并用Vue-Router来控制它们的显示与切换。

Discover.vue:

<template>
 <div>
 <h1>发现音乐</h1>
 </div>
</template>

Friends.vue

<template>
 <div>
 <h1>关注</h1>
 </div>
</template>

My.vue

<template>
 <div>
 <h1>我的音乐</h1>
 </div>
</template>

三个组件都需要链接对应关系,这就需要用Vue-Router来描述。

  • 声明路由链接和站位标签

可以使用<router-link>标签来声明路由链接,并使用<router-view>标签来声明路由站位符。

我们在根组件 App.vue 中进行路由的跳转,代码如下:

 <!--声明路由链接-->
 <router-link to="/discover">发现音乐</router-link>
 <router-link to="/friends">关注</router-link>
 <router-link to="/my">我的音乐</router-link>

这时App组件上就有三个按钮,有兴趣可以用CSS进行样式美化。这时候点击但是还无法跳转。因为定义的链接和三个组件的对应关系还没有设置。因为对应关系比较复杂,可以放到单独的 js 文件中写。

  • 创建路由模块

在项目 src 中创建一个 router 文件夹,在里面新建一个名为 index.js 路由模块,在里面定义对应关系,代码如下:

//导入Vue和VueRouter
import VueRouter from "vue-router";
import Vue from "vue";
//导入组件
import Discover from '../components/Discover.vue'
import Friends from '../components/Friends.vue'
import My from '../components/My.vue'
//将VueRouter设置为vue的插件
Vue.use(VueRouter)

const router=new VueRouter({
 //指定hash属性与组件的对应关系
 routes:[
 {path:'/discover',component:Discover},
 {path:'/friends',component:Friends},
 {path:'/my',component:My},
 ]
})

path对应链接;comment对应组件。

此时,组件要显示到哪里去?这就需要站位标签<router-view>。需要组件在哪里显示<router-view>就放到哪里。我们以放到根组件 App.vue 举例,代码如下:

一旦用户点击了“发现音乐”,浏览器就会跳转的 discover 。根据前面路由的定义discover 对应的是 Discover 组件。这时Discover 组件的内容就会被渲染到<router-view>这个位置,从而完成界面的跳转切换。

下面需要在 index.js 中将路由导出,代码如下:

export default router

最后在main.js 中导入并设置,代码如下:

import Vue from 'vue'
import App from './App.vue'
import router from './router/index'

Vue.config.productionTip=false

new Vue({
 render: h=> h(App),
 router:router
}).$mount('#app')

运行 npm run serve 启动项目。

我们发现没有显示下面的视图,点击“发现音乐”等,链接才会切换,这就可以显示出来了。

第一次加载是到首页,如果这个时候加载组件而没有内容显示,这样也不合适。实际项目中会指定一个默认加载的组件。如网易云音乐中,进入首页默认是进入“发现音乐”组件。

3.vue-router进阶

  • 路由重定向

用户在访问地址A的时候,强制用户跳转到地址B,从而显示特定组件的页面。

通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向。

例如将首页重定义为显示“发现音乐”组件

{path:'/',redirect:"/discover"},



  • 嵌套路由

可以在组件下再嵌套组件,比如在“发现音乐”下再嵌套“推荐”、“歌单”等子路由。

在Discover.vue组件中,声明 toplist 和 playlist 的子路由链接以及子路由占位符,代码如下:

<template>
 <div>
 <h1>发现音乐</h1>
 <!--子路由链接-->
 <router-link to="/discover/toplist">推荐</router-link>
 <router-link to="/discover/playlist">歌单</router-link>
 <hr>
 <router-view></router-view>
 </div>
</template>

这个时候就需要新建 Toplist 和 Playlist 两个组件。

然后在 index.js 中引入Toplist 和 Playlist 两个组件,然后通过 children 属性嵌套声明子路由的方式来设置对应关系。这时index.js 完整代码如下:

//导入Vue和VueRouter
import VueRouter from "vue-router";
import Vue from "vue";
//导入组件
import Discover from '../components/Discover.vue'
import Friends from '../components/Friends.vue'
import My from '../components/My.vue'
import Toplist from '../components/Toplist.vue'
import Playlist from '../components/Playlist.vue'
//将VueRouter设置为vue的插件
Vue.use(VueRouter)

const router=new VueRouter({
 //指定hash属性与组件的对应关系
 routes:[
 //当用户访问 / 时,调转到 /discover
 {path:'/',redirect:"/discover"},
 {path:'/discover',
 component:Discover,
 //通过 children 属性,可以嵌套声明子路由
 children:[
 {path:"toplist",component:Toplist},
 {path:"playlist",component:Playlist},
 ]
 },
 {path:'/friends',component:Friends},
 {path:'/my',component:My},
 ]
})

//导出默认路由
export default router


  • 动态路由

很多路由链接,如下:

<router-link to="prodect/1">商品1</router-link>
<router-link to="prodect/2">商品2</router-link>
<router-link to="prodect/3">商品3</router-link>
const router=new VueRouter({
 //指定hash属性与组件的对应关系
 routes:[
 {path:"prodect/1",component:Prodect},
 {path:"prodect/2",component:Prodect},
{path:"prodect/3",component:Prodect},
 ]
 },
 {path:'/friends',component:Friends},
 {path:'/my',component:My},
 ]
})

上述方式复用性非常差。

思考:如有一个商品列表,当用户点商品的时候就跳转到该商品的详情,每一个商品都会有商品详情,不可能给每一个商品写一个商品详情的组件。这时就希望跳转到详情组件的时候重用组件里面的东西。

动态路由:就是把Hash地址中可变的部分定义为参数项,从而提高路由规则的复用性。在 vue-router 中使用英文的冒号 ( : )来定义路由参数项,如下:

{path : '/prodect/:id,component:Prodect'}

下面进行实例演示:

1.有商品就需要先建一个商品组件:Prodect.vue

2.假设商品组件是基于 My.vue 组件的子路由,修改 My.vue 组件,如下:

<template>
 <div>
 <h1>我的音乐</h1>
 <router-link to="/My/1">商品1</router-link>
 <router-link to="/My/2">商品2</router-link>
 <router-link to="/My/3">商品3</router-link>
 <router-view></router-view>
 </div>
</template>

3.在 index.js 中设置对应关系,先导入 Prodect.vue 组件

import Prodect from '../components/Prodect.vue'

4.使用 children 属性定义跳转,代码如下:

{path:'/my',
 component:My,
 children:[
 {path:":id",component:Prodect},
 ]
 },

5.启动项目,在浏览器中就可以显示效果:点击“我的音乐”,然后在显示的商品1/2/3 中任点 一个,都可以显示“商品”这个内容出来。

现在有一个问题,在跳转到 Prodect.vue 组件时,如何知道需要显示商品几的详情呢?

解决方法:

方法1:通过动态路由匹配的方式渲染出来的组件中,可以使用 $route.params 对象访问到动态匹配的参数项,比如在商品详情组件的内部,根据 id 值,请求不同的商品数据。修改代码如下:

这时,点击不同的商品就显示出是商品几的详情

方法2:为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props 传参,index.js 中修改示例代码如下:

{path:":id",component:Prodect,props:true},

Prodect.vue 组件修改如下:首先定义一个参数 id ;然后就不需要 $route.params,可以直接用于 id 来传递参数了,浏览器显示效果同上。

<template>
 <h3>商品{{ id }}</h3>
</template>

<script>
export default {
 props:["id"]
}
</script>


  • 编程式导航(在此仅作了解,后面的综合运用中再详细演示)

声明式导航:<router-link :to "....">

编程式导航:router.push(...)

除了使用<router-link>创建 a 标签来定义导航链接,还可以借助 router 的实例方法,通过编写代码来实现。

想要导航到不同的 URL ,可以使用 router.push 方法。这个方法会向 history 栈添加一个新的记录。所以,当用户点击浏览器“后退”按钮时,则回到之前的 URL 。

当点击 <router-link>时,这个方法会在内部调用。所以,点击<router-link :to "....">等同于调用router.push(...) 。

<template>
 <div>
 <h3>推荐</h3>
 <button @click="gotoProduct(2)">跳转到商品2</button>
 </div>
</template>

<script>
export default {
 methods:{
 gotoProduct:function(id){
 this.$router.push('/movie/${id}')
 }
 }
}
</script>


  • 导航守卫

导航守卫可以控制路由的访问权限

比如还没有登录就想跳转到订单页面,这时可以用路由守卫进行统一控制。

全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限控制。可以使用 router.beforeEach 注册一个全局前置守卫:

router.beforeEach(( to,from,next )=>{
 if ( to.path==='/main' && !isAuthenticated){
 next( '/login' )
 }
 else{
 next()
 }
})

to:即将进入目标

from:当前导航正要离开的路由

在守卫方法中,如果声明了 next 形参,则必须调佣 next()函数,否则不允许用户访问任何一个路由

直接放行:next()

强制停留在当前页面:next(false)

强制跳转到登录页面:next( '/login' )

 早安,我是叶梓,今天是摄影早自习陪伴大家的第749天。我收到了来自邮储银行的小伙伴们的提问:“团队的合影要怎么拍更有活力?”他们说过去有很多的团建活动,拍了不少合影,但看上去总是比较呆板。自己看看、做个纪念也就罢了,但是如果要发出来的话总觉得还是差点意思。

  我觉得这是一个特别重要的事情,而且又很少有人去讲,所以咱们这周的摄影早自习就花点时间来了解一下合影到底应该怎么拍。正好春暖花开了,免不了得你会跟朋友、同事、同学出去玩的时候总得拍几张合影吧,那我们就来聊聊怎么拍比较好看。今天我们先把注意力集中在一个事情上:站位。也就是到底怎样去列队会更好看些。

图一 反面案例 图片来源:rice.edu

  第一张照片是非常典型的合影的站法,几乎是把所有不该犯的问题全都犯了一遍,站出来那个样子是要多尴尬有多尴尬。它唯一做得好一点的就是选择了一个相对比较简洁的背景,但即便如此,右边那个花坛还是太抢眼了,绿色太绿了。所以,我们合影站位的第一个要点还是要选择一个比较简洁的背景。背景它可以是美的,但是它不能是夺目的,抢掉了人物的风头。选择在哪拍照其实是个特别特别重要的事情,不要小看它,不要说“差不多就行了”,这个态度是不对的。

图二 图片来源:kerryregoconsulting.com

  第二个要点是在站位的时候人物和人物要站得尽量的紧一点,与此同时人物的四周(在构图上)要多留些空间。大家一听就明白了,四周留空间还不就是为了让人物与人物之间显得更紧密,关系显得更好一些,对不对?不要给人感觉不好意思站得太近的感觉。

图三 图片来源:sohu.com

  第三个要点是要特别留意人群的整体轮廓。注意,我不是说个人是胖是瘦,不是说人物轮廓,而是人群的整体的外轮廓。比如说图一,你把人物的外轮廓连起来一看,它就是个方形啊!方形是非常无趣的,呆板的。再看看图三,是偶像练习生大合影,是个倒梯形。倒置的梯形既有一种活泼的感觉,又不失稳重,就比刚才的方形要好多了。你以为这个形状是随便来的吗?它是摄影师刻意安排的!是摄影师要跟他们说你们该怎么摆,怎么站。

图四 图片来源:fitcitysa.com

  第四张照片是一个特别简单的粗暴的合影,其实它里面还是有很多问题的,但是不管怎么样,至少它在人群的外轮廓上形成一个非常有趣的两头大,中间小的形状,人物站成了一个弧形,但是摄影师又没有站在圆心上,而是站在了一侧的远一点的位置,形成一个近大远小的有两条曲线构成的外轮廓,非常漂亮。

图五 图片来源:www.zipworld.co.uk

  所以这是我说的第三个要点,人群的外轮廓要加以注意。最好能有些曲线、斜线,有些高低错落就更好了。你又不是士兵,你如果站不到士兵那么整齐,就干脆高低错落一点,显得更生动活泼。我们现在都比较讲究个性,讲究人性,讲究每一个人都有自己的性格,然后共同组成一个团队,所以呢,站队的时候不用太整齐。

图六 图片来源:mullenlowegroup.com

  第四个要点是人物的姿态最好是更自然一些。站着的、坐着的、坐在地上的、甚至是躺着的,随便给你自己去搭配。很明显,如果是都站着的话,第一是姿势不知道该怎么摆,拍出来会是一副非常呆板的样子。第二这个团队会显得没有活力。我们对比下图一里面这些人,只有一个人物的腿稍微有点动作,其他人都太呆板。然后你往下拉到图六,看看这张照片里面的人物,有的坐得高一些,有的坐得低一些,有的是站着的,这样的人物占位就非常舒适自然,有人还把手搭在别人肩膀上,有人在对着旁边那个人竖大拇指,有人笑得不行了,有人把手背在背后,还挺注意形象的,最右边那个人还有一点点严肃……没关系,把你自己的状态展现出来就好,我们更希望通过合影看到的是一个个真实的人物组成的团队,而不是一看就非常拘谨的气氛,那样的合影我们其实都不会成天摆在桌上去看的,太没有意思了。

  所以你最好去找一个最舒服的姿态去站立,如果你是摄影师的话,就引导对方。对方不知道摆什么的话,你就得发出指令了:你坐着,你站着,你把手撘他肩膀上,等等,总之是模拟生活中真实的姿态。

图七 图片来源:theherringlawgroup.com

  第五个,也是今天关于站位的最后一个要点,就是这个团队里面如果有个核心人物的话就要让他站“C位”,也就是站中央。但他也不一定要站在绝对的中央,稍微偏一点在黄金分割线的位置也是可以的。除了站中央以外,其实你还应该让这个主角通过穿着不同的服饰,或者是摆出不同的姿态来凸显这个人物的重要性。服饰方面,如果大家都是灰色的深色的衣物,那你就该来点红色,红围巾往身上一挂,这个人肯定主角了。或者说所有人都穿西装,那这个主角其实可以脱掉西装穿个衬衣,他就是主角了。这就是服饰可以起到的突显的作用。

  另外你也可以去找一个不同的姿态。如果大家都站着,你坐着行不行?大家都坐着,你站着行不行?只要是不一样的姿态,那个人就一定是个关键人物。你还可以让旁边的、周围的人向这个主要人物方向稍微侧一点身,这样一来他就有了一种被大家簇拥的感觉了,不见得要所有的人都都朝向这个主要人物,只要有那么几个人的身体、头部、眼睛的方向朝向这个人物,那么他就会变得非常的明显。

  今天分享的是关于合影的站位技巧,关于合影的问题你们还想了解什么样的知识?欢迎在底部向我留言,我非常期待你们的提问。关于上周的免费直播课《摄影评片会》,现在已经可以回看了,大家可以点击下方蓝色“了解更多”或打开网易云课堂搜索“你的照片我来评”,找到第6期就可以看到评片会的回放视频。

  今天是摄影早自习陪伴大家的第749天,我是叶梓,每天早上6点半,微信公众号“摄影早自习”,不见不散。

【摄影评片会】回看

【观看方法1】点击下方蓝色“了解更多

【观看方法2】打开网易云课堂网页或APP,搜索:“你的照片我来评”,选择课时6观看

加入“摄影早自习”【微信群】

1、添加叶梓老师微信:leonyee7

2、说明入群(暗号:头条)

【微博】@叶梓

【QQ群】384277488

【微博超级话题】#365天拍摄计划#

【摄影自习室】知识星球(APP)搜索:摄影自习室

原文链接:http://www.katoclass.com/zaozixi20170416.html