<template>
<view class="content">
<div class="reportInstrument">
<u-button
:ripple="true"
style="width:100%;"
shape="circle"
@click="render.headelReport"
type="primary">预览下载PDF</u-button>
</div>
<div id="printReport">
<view class="bold fs14 priceZj">
<view class="u-flex ">
<view class="w_30">小计:</view>
<view class="w_70">¥300000</view>
</view>
<view class="u-flex ">
<view class="w_30">销售税:</view>
<view class="w_70">¥1000</view>
</view>
<view class="u-flex ">
<view class="w_30">运输和处理:</view>
<view class="w_70">¥30000</view>
</view>
<view class="u-flex ">
<view class="w_30">总计:</view>
<view class="w_70">¥09900</view>
</view>
</view>
</div>
<u-gap height="100"></u-gap>
</div>
</div>
</view>
</template>
<script>
/**
* base64字符串转成文件
* @param {String} base64Str // 允许包含前缀
* @param {String} fileName // 文件名称:1663061363470.xlsx
* @param {Object} callback // 返回本地路径径URL,file:///xxx/doc/1663062980631.pdf
*/
function base64ToFile(base64Str, fileName, callback) {
// 去除base64前缀
var index = base64Str.indexOf(',')
var base64Str = base64Str.slice(index + 1, base64Str.length)
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
fs.root.getFile(fileName, {
create: true
}, function(entry) {
// 获得本地路径URL,file:///xxx/doc/1663062980631.pdf
var fullPath = entry.fullPath;
let platform = uni.getSystemInfoSync().platform
if (platform == 'android') {
var Base64 = plus.android.importClass("android.util.Base64");
var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");
try {
// console.log("base64Str: ", base64Str);
var out = new FileOutputStream(fullPath);
// 此处Base64.decode有长度限制,如果不能满足需求,可以考虑换成官方原生插件市场的【Base64转文件】
var bytes = Base64.decode(base64Str, Base64.DEFAULT);
// console.log("bytes: ", bytes);
if (!bytes) {
plus.nativeUI.toast("页面元素过多,超出生成限制,生成失败");
return false
} else {
out.write(bytes);
out.close();
// 回调
callback && callback(entry.toLocalURL());
}
} catch (e) {
console.log(e.message);
}
} else if (platform == 'ios') {
var NSData = plus.ios.importClass('NSData');
var nsData = new NSData();
nsData = nsData.initWithBase64EncodedStringoptions(base64Str, 0);
if (nsData) {
nsData.plusCallMethod({
writeToFile: fullPath,
atomically: true
});
plus.ios.deleteObject(nsData);
}
// 回调
callback && callback(entry.toLocalURL());
}
})
})
}
export default {
data() {
return {
title: 'Hello',
commodityList:[
{
'commodity':' 捷途大圣2023 ',
'specifications':'1',
'unitPrice':'40000',
'number':'2',
'price':'80000',
},
{
'commodity':' 捷途大圣2023 1',
'specifications':'1',
'unitPrice':'40000',
'number':'2',
'price':'80000',
}
],
}
},
onLoad() {
},
methods: {
savePDF(base64) {
uni.showLoading({
title: '导出中'
});
console.log('base64图片--',base64)
var fileName = (new Date()).valueOf() + '.pdf';
base64ToFile(base64, fileName, function(path) {
console.log('result', path);
uni.hideLoading()
uni.showModal({
title: '导出成功',
content: '文件地址:' + path +
'\n 是否打开?',
success: function(res) {
if (res.confirm) {
plus.runtime.openFile(path); //用第三方程序打开文件
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
})
}
}
}
</script>
<script module="render" lang="renderjs">
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
data() {
return {
}
},
mounted() {},
methods: {
headelReport(e, ownerVm) {
html2Canvas(document.querySelector('#printReport'), {
allowTaint: false, //允许污染
taintTest: true, //在渲染前测试图片(没整明白有啥用)
useCORS: true, //使用跨域(当allowTaint为true时这段代码没什么用,下面解释)
}).then(function(canvas) {
let contentWidth = canvas.width
let contentHeight = canvas.height
//一页pdf显示html页面生成的canvas高度;
let pageHeight = contentWidth / 592.28 * 841.89
//生成pdf的html页面高度
let leftHeight = contentHeight
//页面偏移
let position = 0
//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
// canvas.crossOrigin="anonymous";
let pageData = canvas.toDataURL('image/jpeg', 1.0);
let PDF = new JsPDF('', 'pt', 'a4')
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
//避免添加空白页
PDF.addPage()
}
}
}
var _this = this
plus.android.requestPermissions(['android.permission.WRITE_EXTERNAL_STORAGE'], function(e) {
if (e.deniedAlways.length > 0) { //权限被永久拒绝
// 弹出提示框解释为何需要读写手机储存权限,引导用户打开设置页面开启
uni.showModal({
title: '存储权限',
content: '您拒绝了存储权限,请去设置-应用开启存储权限。',
success: function(res) {
if (res.confirm) {
// console.log('用户点击确定');
} else if (res.cancel) {
// console.log('用户点击取消');
}
}
});
}
if (e.deniedPresent.length > 0) { //权限被临时拒绝
// 弹出提示框解释为何需要读写手机储存权限,可再次调用plus.android.requestPermissions申请权限
plus.android.requestPermissions(['android.permission.WRITE_EXTERNAL_STORAGE'])
// console.log('666666666 ' + e.deniedPresent.toString());
}
if (e.granted.length > 0) { //权限被允许
//调用依赖获取读写手机储存权限的代码
let base64Str = PDF.output('dataurlstring');
// console.log("base64Str: ", base64Str);
ownerVm.callMethod('savePDF', base64Str)
}
}, function(e) {
// console.log('R12133313221' + JSON.stringify(e));
});
})
}
}
};
</script>
<style scoped lang="scss">
.reportInstrument{
position:fixed;
width:100%;
left: 0;
bottom: 0;
}
.content{
.w_20{width:20%;}
.w_80{width: 80%;}
.lawReportcontent{
padding:30rpx;
.headBg{
background:rgb(95, 136, 255);
padding:15rpx;
color: #fff;}
.ReportTitle{
.bodborder{
background: #f7f7f7;
line-height:60rpx;
padding:10rpx;
}
.w_50{width:50%;}
}
}
.commodityany{
line-height:50rpx;
padding-top:15rpx;
border-bottom:1px solid rgb(95,136,255);
padding-bottom:15rpx;}
.bold{font-weight:bold;}
.c_red{color:red;}
.b_blue{color:rgb(95,136,255);}
.w_30{width:50%;}
.w_70{width:50%;}
.priceZj{
background: rgb(93 ,158,230);
color: #fff;
line-height:45rpx;
margin-top: 10rpx;
padding: 20rpx;
}
}
</style>
网友评论