最近在弄那个打印的东西。花了差不多将近三天时间,打印样式要根据需求慢慢调整,所以花的时间比较多,这篇文章主要是纪录用Lodop插件实现打印和bootstrap模态框的实现。
打印的文件差不多就是长这样子的
- Lodop打印功能实现
- booststrap模态框
一、Lodop打印的实现
1、首先要下载打印插件
http://www.lodop.net/download.html
我选择的是第一个
2、将与之相关的文件放入项目当中
我这个项目用的是SSM框架,这个是老项目,所以没有用springboot,将上面四个文件放到这个文件夹下,上面三个文件放在一个文件夹里,即:
3、在项目中引入上面的四个文件,我是在index.jsp中要实现打印功能的,所以在这个文件引入了上面四个文件
4、我实现的功能是点击打印按钮,进行打印
这个打印方法的实现,主要就是在调用PrPrint方法,实现打印功能,还需要将id传过去,是为了去后台获取打印表格里的数据。
<button type="button" class="btn btn-info btn-sm cbtn-60" onclick="FnPrint() " id="mymodalbtn";>打印</button>
function FnPrint() {
var val;
var type;
var rowid = $("#jqGrid").getGridParam("selrow");
var rowData = $("#jqGrid").getRowData(rowid);
var id = rowData.id;
$("#myModal").modal("show");
$("#btnOption").on("click",function () {
val=$('input:radio[name="options"]:checked').val();
if (id != null && id != undefined && id != "") {
sendPostReq("<%=path%>/sa/settlemain/print.action", {
id: id,
}, function (data) {
console.log()
if(data.result==null)
{
layer.msg("请先审核!");
return;
}
else {
PrPrint("<%=path%>/sa/settlemain/print.action", id,val);
}
});
}
else {
bootbox.alert("请先选择行再操作!");
}
$("#myModal").modal("hide");
})
}
5、打印具体样式的调整就是在Print.js文件中,下面代码就是Print.js文件的全部代码。
//打印销售发货结算表
function PrPrint(url, id, val) {
//print();
$.ajax({
type: "GET",
url: url,
cache: false,
async: false,
data: { id: id ,type: val},
dataType: 'json',
success: function (result) {
if(result.result.data!=null) {
if(result.result.dataDetail1==null)
{
console.log("合并")
printcount(result.result.data,result.result.customer,result.result.dataDetail)
}
else {
console.log("分开")
printcount(result.result.data,result.result.customer,result.result.dataDetail)
printcount(result.result.data,result.result.customer,result.result.dataDetail1)
}
}
}
});
}
//这个方法主要是实现了,将多出来的数据打印在第二张纸上,因为打印每一张纸限制了只能打印十条数据,多的数据就要放在第二张纸上了
function printcount(data,customer,datadetail) {
var mList = new Array();
var dList = new Array();
for (var i = 0; i < datadetail.length; i++) {
if (i != 0 && i % 10 == 0) {
mList.push(dList);
dList = new Array();
}
var d = datadetail[i];
dList.push(d);
}
if (dList.length > 0) {
mList.push(dList);
}
for (var i = 0; i < mList.length; i++) {
print(data,customer,mList[i])
}
}
function print(data,customer,datadetail) {
LODOP = getLodop();
LODOP.PRINT_INITA(0,0,800,1100,"配件合同");
LODOP.SET_PRINT_PAGESIZE(1,0,0,"A4");
LODOP.SET_PRINT_MODE("PRINT_NOCOLLATE",1);
LODOP.ADD_PRINT_TEXT(41,317,160,35,"销售发货结算单");
LODOP.SET_PRINT_STYLEA(0,"FontSize",15);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(75,15,100,25,"客户名称:");
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(75,90,100,25,data.custName);
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(75,267,100,25,"联系人:");
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(75,335,100,25,customer.contactPerson);
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(78,547,100,25,"日期:");
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(78,595,100,25,data.settleDate);
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(97,14,100,29,"客户地址:");
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(97,89,100,29,customer.custAddress);
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(98,268,100,25,"联系电话:");
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(98,345,100,25,customer.contactPersonTel);
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
// LODOP.SET_PRINT_STYLEA(0,"ItemType",1);
LODOP.ADD_PRINT_TEXT(98,547,100,25,"销售订单:");
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
LODOP.ADD_PRINT_TEXT(98,621,124,25,data.saleCode);
LODOP.SET_PRINT_STYLEA(0,"FontSize",12);
LODOP.ADD_PRINT_TABLE(121,12,726,351,CreateTableDetail(datadetail));
LODOP.ADD_PRINT_TEXT(458+datadetail.length, 13, 100, 25, "第一联:存根");
LODOP.ADD_PRINT_TEXT(458+datadetail.length, 125, 100, 25, "第二联:财务");
LODOP.ADD_PRINT_TEXT(458+datadetail.length, 224, 100, 22, "第三联:门卫");
LODOP.ADD_PRINT_TEXT(458+datadetail.length, 332, 100, 25, "第四联:回单");
LODOP.ADD_PRINT_TEXT(458+datadetail.length, 457, 100, 25, "第五联:客户");
LODOP.ADD_PRINT_TEXT(479+datadetail.length, 14, 121, 25, "制单人(盖章):");
LODOP.ADD_PRINT_TEXT(479+datadetail.length, 108, 121, 25, data.createUser);
LODOP.ADD_PRINT_TEXT(479+datadetail.length, 234, 110, 25, "审核人(盖章):");
LODOP.ADD_PRINT_TEXT(479+datadetail.length, 406, 105, 25, "送货人(盖章):");
LODOP.ADD_PRINT_TEXT(479+datadetail.length, 590, 105, 25, "收货人(盖章):");
//LODOP.PRINT_SETUP();
// LODOP.PREVIEW();
LODOP.PRINT();
// LODOP.PRINT_SETUP();
// LODOP.PRINT_DESIGN();
}
function CreateTableDetail(result) {
var css = "<style> table,td,th {border: 1px solid black;border-style: solid;border-collapse: collapse;}</style><table border=1>";
var td= " <tr style='height:26px' align='center'> <td style='width:80px'>序号</td><td style='width:240px'>货品名称</td><td style='width:130px'>规格</td><td style='width:150px'>产品标准</td><td style='width:100px'>框数</td><td style='width:130px'>只数</td><td style='width:130px'>均重</td><td style='width:130px'>单位</td>" +
"<td style='width:130px'>重量</td><td style='width:130px'>单价</td><td style='width:130px'>金额</td></tr>"
var iamount=0;
var piece=0;
var qty=0;
var weight=0;
for (var i = 0; i < result.length; i++) {
td = td+"<tr ><td align='center'>" + (i+1) + "</td>" +
"<td style='height:26px' align='center' style='width:240px' >" + result[i].invName + "</td><td align='center' style='word-wrap:break-word;word-break:break-all;'>" + result[i].invSpecName + "</td><td align='center' style='word-wrap:break-word;word-break:break-all;'>" + result[i].invStandardName + "</td><td align='center'>" + result[i].deliveryPiece + "</td><td align='center'>" + result[i].deliveryQty + "</td><td align='center'>" + result[i].averageProductionWeight + "</td><td align='center'>kg</td>" +
"<td align='center'>" + result[i].deliveryWeight + "</td><td align='center'>" + result[i].factSalePrice + "</td><td align='center'>" + result[i].factSaleAmount + "</td></tr>"
iamount=iamount+( result[i].factSaleAmount-0);
piece=piece+(result[i].deliveryPiece)
qty=qty+(result[i].deliveryQty)
weight=weight+(result[i].deliveryWeight)
}
if(result.length<10)
{
for(var i=result.length;i<10;i++)
{
td = td+"<tr style='height:25px' align='center' ><td align='center'></td><td align='center' style='word-wrap:break-word;word-break:break-all;' ></td><td align='center' style='word-wrap:break-word;word-break:break-all;'></td><td align='center' style='word-wrap:break-word;word-break:break-all;'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td>" +
"<td align='center'></td><td align='center'></td><td align='center'></td></tr>"
}
}
td = td+"<tr style='height:25px' align='center'><td colspan=4>合计</td><td >"+piece+" </td><td >"+qty+" </td> <td > </td> <td > </td> <td >"+weight+" </td><td > </td><td >"+iamount+" </td></tr>";
td = td+"<tr style='height:25px' align='left'><td colspan=4>金额(大写):"+convertCurrency(iamount)+"</td><<td style='font-size: 11px' >上日余额 </td><td colspan='2'> </td> <td >余额 </td><td > </td> <td style='font-size: 14px'>欠框子数 </td><td > </td></tr>";
var txt = css + td+ "</table>";
return txt;
}
//该方法实现了将数字转换为大写的
function convertCurrency(money) {
//汉字的数字
var cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
//基本单位
var cnIntRadice = new Array('', '拾', '佰', '仟');
//对应整数部分扩展单位
var cnIntUnits = new Array('', '万', '亿', '兆');
//对应小数部分单位
var cnDecUnits = new Array('角', '分', '毫', '厘');
//整数金额时后面跟的字符
var cnInteger = '整';
//整型完以后的单位
var cnIntLast = '元';
//最大处理的数字
var maxNum = 999999999999999.9999;
//金额整数部分
var integerNum;
//金额小数部分
var decimalNum;
//输出的中文金额字符串
var chineseStr = '';
//分离金额后用的数组,预定义
var parts;
if (money == '') { return ''; }
money = parseFloat(money);
if (money >= maxNum) {
//超出最大处理数字
return '';
}
if (money == 0) {
chineseStr = cnNums[0] + cnIntLast + cnInteger;
return chineseStr;
}
//转换为字符串
money = money.toString();
if (money.indexOf('.') == -1) {
integerNum = money;
decimalNum = '';
} else {
parts = money.split('.');
integerNum = parts[0];
decimalNum = parts[1].substr(0, 4);
}
//获取整型部分转换
if (parseInt(integerNum, 10) > 0) {
var zeroCount = 0;
var IntLen = integerNum.length;
for (var i = 0; i < IntLen; i++) {
var n = integerNum.substr(i, 1);
var p = IntLen - i - 1;
var q = p / 4;
var m = p % 4;
if (n == '0') {
zeroCount++;
} else {
if (zeroCount > 0) {
chineseStr += cnNums[0];
}
//归零
zeroCount = 0;
chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
}
if (m == 0 && zeroCount < 4) {
chineseStr += cnIntUnits[q];
}
}
chineseStr += cnIntLast;
}
//小数部分
if (decimalNum != '') {
var decLen = decimalNum.length;
for (var i = 0; i < decLen; i++) {
var n = decimalNum.substr(i, 1);
if (n != '0') {
chineseStr += cnNums[Number(n)] + cnDecUnits[i];
}
}
}
if (chineseStr == '') {
chineseStr += cnNums[0] + cnIntLast + cnInteger;
} else if (decimalNum == '') {
chineseStr += cnInteger;
}
return chineseStr;
}
关于打印的实现,代码基本上就是这些了。接下来讲解bootstrap模块框弹出框的问题,这个也是我在实现打印这个东西过程中需要实现的一个功能,就是在点击打印时,弹出框进行打印规则的选择,打印规则有合并和分开两种规格,合并就是把规格是ABM的打印在一起,那么分开就是指AB打印在一起,M单独打印,这个ABM是产品的一个规格,规格就是一张表里的一个字段。
bootstrap模态框实现
1、引入bootstrap相关的js和css
<script type="text/javascript" src="js/jquery-3.3.1.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.bootcss.com/jquery/3.4.1/core.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
2、将模态框代码放到自己项目中,网上例子很多。
<!-- 模态框(Modal) -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<h4 class="modal-title" id="myModalLabel">
选择打印类型
</h4>
</div>
<div class="modal-body">
<input style="margin-left: 40px;font-size: 50px;"width="100px" type="radio" name="options" id="options1" checked="checked" value="合并">合并
<input style="margin-left: 80px" type="radio" name="options" id="options2" value="分开">分开
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭
</button>
<button type="button" class="btn btn-primary" id="btnOption" >
确定
</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
这个模态框弹出的样子就是下面图片里的这个样子
3、实现点击确定按钮时,获取到单选框的值,也就是获取到合并还是分开这两个其中的一个值。
点击打印弹出模态框
$("#myModal").modal("show");
点击确定按钮时获取radio里的值
$("#btnOption").on("click",function () {
val=$('input:radio[name="options"]:checked').val();
并将模态框隐藏
$("#myModal").modal("hide");