打印收款单据(easypoi)Vue+springBoot+Mybatisplus

打印pdf单据(模板)

前端

先导入printJS
yarn add print-js
<template>
  <a-card>
    <div>
      <a-button @click="receipt(billNo)" type="primary">打印</a-button>
      <div
        class="tables"
      >
        <div style="width: 1000px" id="pdfDom">
          <p align="center" class="title">中百物业收款收据</p>
          <div style="width: 100%;margin-bottom: 10px;">
            <div style="width: 35%;float: left;font-weight:bold">房间:{{ Receipt.roomNo }} </div>
            <div style="width: 35%;float: left;font-weight:bold">建筑面积(平方米): {{ Receipt.buildArea }}</div>
            <div style="width: 30%;float: right;font-weight:bold">收据编号:{{ billNo }} </div>
          </div>
          <div style="width: 100%;margin-bottom: 10px;">
            <div style="width: 35%;float: left;font-weight:bold">业主 : {{ Receipt.ownerName }}</div>
            <div style="width: 35%;float: left;font-weight:bold">收款类型: {{ Receipt.payType }}</div>
            <div style="width: 30%;float: right;font-weight:bold">收款日期:{{ (Receipt.payTime || '').split(' ')[0] }}</div>
          </div>
          <table class="table" id="printpdf">
            <tr >
              <td colspan="2" width="220">费用项目</td>
              <td colspan="2" width="220">起始日期</td>
              <td colspan="2" width="220">截止日期</td>
              <td colspan="2" width="200">单价</td>
              <td colspan="2" width="170">费用金额</td>
              <td colspan="2" width="170">上月数</td>
              <td colspan="2" width="170">本月数</td>
              <td colspan="2" width="390">实用量</td>
              <td colspan="2" width="220">本次实收</td>
            </tr>
            <tr v-for="(item,index) in receiptData" :key="index">
              <td colspan="2" width="200">{{ item.itemText }}</td>
              <td colspan="2" width="170">{{ (item.startTime || '').split(' ')[0] }}</td>
              <td colspan="2" width="170">{{ (item.endTime || '').split(' ')[0] }}</td>
              <td colspan="2" width="170">{{ item.price }}</td>
              <td colspan="2" width="170">{{ item.amount }}</td>
              <td colspan="2" width="170">{{ item.startRecord }}</td>
              <td colspan="2" width="170">{{ item.endRecord }}</td>
              <td colspan="2" width="170">{{item.record}}</td>
<!--              <td colspan="2" width="170">{{ item.discountAmount }}</td>-->
              <td colspan="2" width="170">{{ item.actualAmount }}</td>
            </tr>
            <tr>
              <td colspan="2" width="300">合计(人民币大写)</td>
              <td colspan="6" width="220"></td>
              <td colspan="2" width="220">{{ Receipt.totalAmount }}</td>
              <td colspan="4" width="220"></td>
              <td colspan="2" width="220">优惠:{{Receipt.totalDiscountAmount }}</td>
              <td colspan="2" width="200">{{ Receipt.totalActualAmount }}</td>
            </tr>
          </table>
          <div style="width: 100%;margin-bottom: 10px;">
            <div style="width: 30%;float: left;font-weight:bold">结算人:{{Receipt.employeeName}}</div>
            <div style="width: 35%;float: left;font-weight:bold">服务电话:</div>
          </div>
        </div>
      </div>
    </div>
  </a-card>
</template>

<script>
import { receiptPdf } from '@api/productManager/personnelUnit/ownerInfo'
import printJS from 'print-js'
import { getReceipt } from '../../../../api/fee/inquiry'
export default {
  name: 'BillPrint',
  data () {
    return {
      loading: false,
      tableData: [],
      Receipt: {
        ownerName: '',
        buildArea: '',
        payType: '',
        payUserId: '',
        payTime: '',
        payUsername: '',
        payStatus: '',
        refundAmount: '',
        refundTime: '',
        tenantId: '',
        deptId: '',
        remarks: '',
        phone: '',
        startTime: '',
        endTime: '',
        price: '',
        startRecord: '',
        endRecord: '',
        area: '',
        amount: '',
        DiscountAmount: '',
        actualAmount: '',
        billNo: '',
        employeeName: '',
        roomNo: ''
      },
      receiptData: [],
      pagination: {
        pageSize: 10,
        current: 1,
        total: 0
      },
      pages: {
        size: 10,
        current: 1
      },
      billNo: 0
    }
  },
  methods: {
    init () {
      this.loading = true
      this.billNo = this.$route.query.billNo
      console.log('billNo', this.billNo)
      getReceipt(this.billNo).then(res => {
        this.receiptData = res.data
        this.receiptData.forEach(da => {
          da.price = da.price / 100.0
          da.amount = da.amount / 100.0
          da.buildArea = da.buildArea / 100.0
          da.endRecord = da.endRecord / 100.0
          da.startRecord = da.startRecord / 100.0
          da.discountAmount = da.discountAmount / 100.0
          da.actualAmount = da.actualAmount / 100.0
          da.record = da.endRecord - da.startRecord
        })
        this.Receipt = res.data[0]
        this.Receipt.totalAmount = this.Receipt.totalAmount / 100.0
        this.Receipt.totalActualAmount = this.Receipt.totalActualAmount / 100.0
      })
      console.log('data', this.num)
    },
    receipt (id) {
      this.loading = true
      receiptPdf(id).then(res => {
        console.log(res)
        const blob = new Blob([res], { type: 'application/pdf' })
        const url = URL.createObjectURL(blob)
        printJS({
          printable: url,
          type: 'pdf'
        })
      }).catch(err => {
        this.$message.error(err.msg)
      })
    }
  },
  created () {
    this.init()
  }
}
</script>

<style scoped>
  .table p {
    text-align: center;
    margin: 10px 0;
    color: #000c17;
    font-size: 18px;
  }
  .table{
    border-style: solid;
    border-width: 1.0pt;
    font-variant: normal;
  }
  td{
    border-style: solid;
    border-width: 1.0pt;
  }
  .centent > p{
    float: left;
    font-size: 18px;
    font-variant: normal;
    color: #000c17;
  }
  .tables{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
  #pdfDom{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
  .title{
    font-size: 30px;
    font-variant: normal;
  }
</style>

在这里插入图片描述

后端

用的是easypoi
在这里插入图片描述
模板不会写的,可以去看官方文档 easyoi ,很详细。
在这里插入图片描述

  /**
     * 打印收款单
     */
    @Override
    public void downloadReceipt(String id, HttpServletResponse response) throws IOException {
        Map<String,Object> map= new HashMap<>();
        List<PropertyPaymentDetailDTO> list=propertyPaymentDetailMapper.getReceipt(Long.valueOf(id));
        list.stream().peek(item->{
            if (item.getType().equals("3")){
                item.setPrice(0L);
            }
            if (!item.getType().equals("2")){
                item.setStartRecord(0L);
                item.setEndRecord(0L);
            }
        }).collect(Collectors.toList());
        PropertyPayment propertyPayment =propertyPaymentMapper.selectOne(new LambdaQueryWrapper<PropertyPayment>().eq(PropertyPayment::getBillNo,id));
        map.put("billNo",id);
        map.put("payTime",propertyPayment.getPayTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        map.put("totalAmount",propertyPayment.getTotalAmount() / 100.0);
        map.put("totalActualAmount",propertyPayment.getTotalActualAmount() / 100.0);
        map.put("amountCapital", convertRMB.toRMBUpper(String.valueOf(propertyPayment.getTotalActualAmount() / 100.0)));
        List<Map<String,String>> listMap= new ArrayList<Map<String, String>>();
        list.stream().peek(item->{
            Map<String,String> lm=new HashMap<String, String>();
            lm.put("itemText",item.getItemText());
            lm.put("startTime",item.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            lm.put("endTime",item.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            lm.put("price",String.valueOf(item.getPrice() / 100.0));
            lm.put("amount",String.valueOf(item.getAmount() / 100.0));
            lm.put("startRecord",String.valueOf(item.getStartRecord() / 100.0));
            lm.put("endRecord",String.valueOf(item.getEndRecord() / 100.0));
            lm.put("num",String.valueOf(item.getEndRecord() /100.0 - item.getStartRecord() / 100.0));
            lm.put("actualAmount",String.valueOf(item.getActualAmount() / 100.0));
            listMap.add(lm);
            map.put("roomNo",item.getRoomNo());
            map.put("ownerName",item.getOwnerName());
            map.put("buildArea",item.getBuildArea() / 100.0);
            map.put("employeeName",item.getEmployeeName());
            map.put("totalDiscountAmount",String.valueOf(item.getTotalDiscountAmount() / 100.0));
        }).collect(Collectors.toList());
        map.put("maplist",listMap);
        TemplateExportParams params = new TemplateExportParams("templates/reciptExcel.xlsx");
        Workbook workbook= ExcelExportUtil.exportExcel(params,map);
        response.setCharacterEncoding("UTF-8");
        response.addHeader("Access-Control-Allow-Headers", "Content-Disposition");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("收据表.pdf", "UTF-8"));
        File templateFile = FileUtil.touch("classpath:templates/temp.xlsx");
        FileOutputStream outputStream = new FileOutputStream(templateFile);
        workbook.write(outputStream);
        FileInputStream inputStream = new FileInputStream(templateFile);
        ExcelToPdf.excel2pdf(inputStream, response.getOutputStream());

    }

只展示了实现的方法
最后是EXCEL转的PDF格式,打印的是PDF,这里还需要一个去水印的方法。
就是上面util下面的ExcelToPdf,代码粘在下面了

import com.aspose.cells.License;
import com.aspose.cells.SaveFormat;
import com.aspose.cells.Workbook;
import lombok.extern.slf4j.Slf4j;

import java.io.InputStream;
import java.io.OutputStream;

/**
 * @author: XYS
 * @date: 2019/8/17 16:16
 */
@Slf4j
public class ExcelToPdf {
    private static void getLicense() {
        try {
//            File templateFile = FileUtil.file("classpath:templates/license.xml");
//            FileInputStream inputStream = new FileInputStream(templateFile);
//            ClassPathResource classPathResource = new ClassPathResource("classpath:templates/license.xml");
            InputStream is = ExcelToPdf.class.getClassLoader().getResourceAsStream("templates/license.xml"); //  license.xml应放在..\WebRoot\WEB-INF\classes路径下
            License aposeLic = new License();
            aposeLic.setLicense(is);
        } catch (Exception e) {
            log.error("获取license 失败 -> {}", e.getLocalizedMessage());
        }
    }

    public static void excel2pdf(InputStream inputStream, OutputStream outputStream) {
        getLicense();
        try {
            Workbook wb = new Workbook(inputStream);// 原始excel路径
            wb.save(outputStream, SaveFormat.PDF);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
最后的效果

在这里插入图片描述

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是使用Vue、ElementUI、MybatisPlus和Spring Boot实现MD5加密的完整代码: 前端代码: ```html <template> <el-form :model="loginForm" ref="loginForm" :rules="rules" label-width="80px" class="login-form"> <el-form-item label="用户名" prop="username"> <el-input v-model="loginForm.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="loginForm.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="login">登录</el-button> </el-form-item> </el-form> </template> <script> import md5 from 'js-md5'; export default { name: 'LoginForm', data() { return { loginForm: { username: '', password: '' }, rules: { username: [{ required: true, message: '请输入用户名', trigger: 'blur' }], password: [{ required: true, message: '请输入密码', trigger: 'blur' }] } }; }, methods: { login() { this.$refs.loginForm.validate(valid => { if (valid) { this.loginForm.password = md5(this.loginForm.password); // 发送登录请求 } else { return false; } }); } } }; </script> ``` 后端代码: ```java import org.apache.commons.codec.digest.DigestUtils; @RestController @RequestMapping("/login") public class LoginController { @PostMapping public Result login(@RequestBody LoginForm loginForm) { String username = loginForm.getUsername(); String password = DigestUtils.md5Hex(loginForm.getPassword()); // 根据用户名和密码验证登录 return Result.success(); } } ``` 以上代码中,前端使用了js-md5库对密码进行MD5加密,后端使用了commons-codec库对密码进行MD5加密。请注意,MD5加密虽然是常用的加密方式,但不是最安全的加密方式。建议在实际开发中,使用更加安全的加密方式,如bcrypt、scrypt等。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值