2021年10月

官网例子:https://tcpdf.org/examples
github: https://github.com/tecnickcom/tcpdf
packagist: https://packagist.org/packages/tecnickcom/tcpdf
之前还看了fpdf类库,支持中文不是很方便,需要一个中文扩展程序,所以就放弃它了。
今天tcpdf是主角,先看一下它的特型。

TCPDF具有以下特性:
1、支持页面页脚;
2、支持HTML标签代码;
3、支持jpg/png/gif/svg图形图像;
4、支持表格;
5、支持中文字符;(有些PDF类不支持中文或者处理中文相当麻烦)
6、自动分页,自动页码,等等。

如何用Laravel生成pdf文档?
由于开发工作用的是Laravel,所以首先需要引入类库,如下:

安装:

composer require tecnickcom/tcpdf

代码:

$pdf = new \TCPDF();
// 设置文档信息
$pdf->SetCreator('懒人开发网');
$pdf->SetAuthor('懒人开发网');
$pdf->SetTitle('TCPDF示例');
$pdf->SetSubject('TCPDF示例');
$pdf->SetKeywords('TCPDF, PDF, PHP');
 
// 设置页眉和页脚信息
$pdf->SetHeaderData('tcpdf_logo.jpg', 30, 'LanRenKaiFA.com', '学会偷懒,并懒出效率!', [0, 64, 255], [0, 64, 128]);
$pdf->setFooterData([0, 64, 0], [0, 64, 128]);
 
// 设置页眉和页脚字体
$pdf->setHeaderFont(['stsongstdlight', '', '10']);
$pdf->setFooterFont(['helvetica', '', '8']);
 
// 设置默认等宽字体
$pdf->SetDefaultMonospacedFont('courier');
 
// 设置间距
$pdf->SetMargins(15, 15, 15);//页面间隔
$pdf->SetHeaderMargin(5);//页眉top间隔
$pdf->SetFooterMargin(10);//页脚bottom间隔
 
// 设置分页
$pdf->SetAutoPageBreak(true, 25);
 
// set default font subsetting mode
$pdf->setFontSubsetting(true);
 
//设置字体 stsongstdlight支持中文
$pdf->SetFont('stsongstdlight', '', 14);
 
//第一页
$pdf->AddPage();
$pdf->writeHTML('<div style="text-align: center"><h1>第一页内容</h1></div>');
$pdf->writeHTML('<p>我是第一行内容</p>');
$pdf->writeHTML('<p style="color: red">我是第二行内容</p>');
$pdf->writeHTML('<p>我是第三行内容</p>');
$pdf->Ln(5);//换行符
$pdf->writeHTML('<p><a href="http://www.lanrenkaifa.com/" title="">懒人开发网</a></p>');
 
//第二页
$pdf->AddPage();
$pdf->writeHTML('<h1>第二页内容</h1>');
 
//输出PDF
$pdf->Output('t.pdf', 'I');//I输出、D下载、 F保存到服务器

本文转自:https://www.jianshu.com/p/4d68aefa820e

overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:3; /**可以修改显示行数。 必须设置 height 属性,不然不生效。**/

1.html

<button type="button" class="layui-btn submit-btn" lay-submit lay-filter="submit-btn">送审</button>

2.1.js

form.on('submit(submit-btn)', function(data){
        //1.防止重复提交:单击之后提交按钮不可选
        let DISABLED = 'layui-btn-disabled';
        //2.防止重复提交:增加样式
        $('.submit-btn').addClass(DISABLED).attr('disabled', 'disabled');
        objs.ajax(data,'{{ route("member.process.submit") }}');
    });

2.2js回调里面

{
    layer.msg(result.msg,{icon:2,time:1000});
    //3.防止重复提交
    $('.submit-btn').removeClass(DISABLED).removeAttr('disabled');
}

//会签
form.on('submit(routing-btn)', function(data) {
    //console.log(data);
    layer.open({
        type: 2,
        title: '选择会签人',
        shade: 0.1,
        area: ['80%', '80%'],
        content: '{{ route("member.process.routing.create") }}?entry_id=' + data.field.entry_id,
        success: function(layero, index){
            //获取iframe内的button值(判断返回的)
            let body = layer.getChildFrame('body', index);
            let values = body.find('button').val();
            if (values) {
                layer.msg('有会签尚未处理,请耐心等待', {
                    icon: 2,
                    time: 1500
                }, function() {
                    layer.close(index);
                    //table.reload('xf-data-table');
                });
            }
        },end: function () {
            parent.layer.close(parent.layer.getFrameIndex(window.name));//关闭当前页
            window.parent.location.reload();
            parent.layui.table.reload("xf-data-table");
        }
    });
});

不同按钮提交到不同form页面

<input type=button onclick="form.action='backup.html';form.submit()" value="标题一">
<input type=button onclick="form.action='optimize.html';form.submit()" value="标题二">
<input type=button onclick="form.action='repair.html';form.submit()" value="标题三">

html

<div class="layui-form-item">
    <div class="layui-inline">
        <label class="layui-form-label">日期范围</label>
        <div class="layui-inline" id="dateRank">
            <div class="layui-input-inline">
                <input type="text" lay-verify="required" autocomplete="off" name="start_time" id="start_time" class="layui-input" placeholder="开始日期">
            </div>
            <div class="layui-form-mid">-</div>
            <div class="layui-input-inline">
                <input type="text" lay-verify="required" autocomplete="off" name="end_time" id="end_time" class="layui-input" placeholder="截止日期">
            </div>
        </div>
    </div>
</div>
<div class="layui-form-item">
    <div class="layui-inline">
        <label class="layui-form-label layui-require">天数</label>
        <div class="layui-input-inline">
            <input name="days" lay-verify="required" class="layui-input" autocomplete="off" id="days" placeholder="请选择开始与截止日期">
        </div>
        <div class="layui-input-inline" style="width: 100px;">
            <input type="button" value="计算天数" onclick="check()" class="layui-btn">
        </div>
    </div>
</div>

js

<script>
    layui.use(['layer','laydate','form'],function(){
        let form = layui.form;
        let $ = layui.jquery;
        let layer = layui.layer;
        let laydate=layui.laydate;

        //选择开始时间
        laydate.render({
            elem: '#dateRank',
            range: ['#start_time', '#end_time'],
        });
    });

    //计算日期
    function check(){
        let start=document.getElementById("start_time").value;//获取起始日期
        let end=document.getElementById("end_time").value;//获取结束日期
        if(start === ""){
            layer.msg("请选择开始日期!", {icon:2,time:1500});
        }
        else if(end === ""){
            layer.msg("请选择截止日期!", {icon:2,time:1500});
        }
        document.getElementById("days").value=getDays(start, end);
    }
    //返回计算天数值
    function getDays(startDate,endDate){
        let date1Str = startDate.split("-");//将日期字符串分隔为数组,数组元素分别为年、月、日
        //根据年、月、日的值创建Date对象
        let date1Obj = new Date(date1Str[0],(date1Str[1]-1),date1Str[2]);
        let date2Str = endDate.split("-");
        let date2Obj = new Date(date2Str[0],(date2Str[1]-1),date2Str[2]);
        let t1 = date1Obj.getTime();//返回从1970-1-1开始计算到Date对象中的时间之间的毫秒数
        let t2 = date2Obj.getTime();//返回从1970-1-1开始计算到Date对象中的时间之间的毫秒数
        let datetime = 1000*60*60*24; //一天时间的毫秒值
        let minusDays = Math.floor(((t2-t1)/datetime));//计算出两个日期天数差
        let days = Math.abs(minusDays);//如果结果为负数,取绝对值
        //console.log(days);
        if(!days) { //在没有选择开始或结束日期时返回"NaN"类型,所以做此判断
            return '';
        }
        return days + 1;
    }
</script>

写在后面:

本文内容主要是参考/拷贝互联网稍加改动,具体网址不记得了,若有冒犯,请联系我删除。13073932#163.com

话不多说,上代码:

html

<a href="javascript:;" id="formLink">
  我是要显示的文字
  <input type="hidden" value="{ $url }" id="content">
</a>

js

$('#formLink').on('click', function(){
     let href = $('#content').val()
     //console.log(href);
     layer.open({
       type: 2,
       title: '新增',
       shade: 0.1,
       area: ['80%', '80%'],
       content: href,
  });
});

这个费了点时间,所以记录下:

App\Exceptions\Handler.php中重写两个方法如下:

/**
 * Convert an authentication exception into a response.
 * @param  \Illuminate\Http\Request  $request
 * @param  \Illuminate\Auth\AuthenticationException  $exception
 * @return \Symfony\Component\HttpFoundation\Response
 */
protected function unauthenticated($request, AuthenticationException $exception)
{
    return $request->expectsJson()
        ? response()->json(['message' => $exception->getMessage()], 401)
        : redirect()->guest($this->redirectTo($exception->guards()) ?? route('login'));
}



/**
 * 重定向跳转至会员中心
 * @param array $guardArr
 * @return string
 */
protected function redirectTo($guardArr = [])
{
    if(in_array('member',$guardArr)){
        return route('member.login');
    }
}

其中关键点是拿到guards()里的门卫名称,根据此来判断:
$exception->guards()得到数据类似['admin','user']再据此判断。