Kinh nghiệm khi code phần view để in ra giấy



Nguyễn Thanh Luận / 07-08-2019

Khi code các dự án liên quan đến quản lý hoặc bán hàng, thỉnh thoảng chúng ta sẽ gặp yêu cầu cần phải in các dữ liệu ra giấy theo mẫu có sẵn như là in hóa đơn đỏ hoặc in các giấy tờ bằng cấp ..etc.

Việc này tưởng chừng đơn giản nhưng thực tế thì ko dễ dàng do mình phải canh chỉnh vị trí của từng cái text một vào đúng vị trí mà khách hàng yêu cầu.

Để thực hiện thao tác in thì hiện nay có 2 cách 1 là tạo file pdf rồi khách hàng sẽ in từ file pdf, cách thứ 2 là in trực tiếp cấu trúc html từ trình duyệt.

cả 2 cách đều yêu cầu là phải tạo dựng cấu trúc trang bằng html. cách thứ 1 có ưu điểm là file pdf ngoài in ra thì cũng có thể làm tài liệu đối chiếu cho khách hàng, tuy nhiên khi chuyển từ html sang pdf thì chỉ sử dụng được css cơ bản nên việc tùy chỉnh trang sẽ khó khăn hơn. cách thứ 2 thì từ trình duyệt mình nhấn Ctr+P thì sẽ hiện ra cửa sổ in. cách này thao tác nhanh hơn và cũng dễ tinh chỉnh vị trí hơn do ko phải qua giai đoạn tạo file pdf.

trong 1 trang html mình có thể chỉnh css để chỉ định section nào được in và section nào ko, chi tiết tham khảo bài viết sau: https://www.tutorialspoint.com/css/css_printing

sau khi đã chỉ định khu vực in ra thì việc còn lại là đổ dữ liệu vào và chỉnh lại vị trí cho đúng. công đoạn chỉnh cần phải thử nghiệm nhiều lần tinh chỉnh theo từng pixel theo ý khách hàng. để việc này hiệu quả thì mình có thể sử dụng thủ thuật sau:

+ toàn bộ nội dung in đưa vào 1 div container div này để position absolute để mình có thể căn chỉnh vị trí tổng thể file in so với lề trái phải trên dưới của trang giấy

+ trong div container mình tạo tiếp 1 div print-container để chứa toàn bộ nội dung in, div này để position: relative để cho toàn bộ con của nó có vị trí đi theo div container ở trên

+ toàn bộ những content con còn lại đều ở trong div print-container và có position absolute để có thể căn chỉnh vị trí theo từng pixel tùy ý( vd khách hàng muốn block a dịch phải 5 px, block B dịch trái 5px ..etc để cho đúng vị trí thật khi in ra.)

+ khi in thử nhớ lưu ý để lại tờ giấy in cho ngay thẳng, đúng vị trí, nếu ko thì mỗi lần in sẽ cho rea 1 kết quả khác nhau

vd: code file in hóa đơn đỏ trên giấy của website lô hội :

id = ‘print-area’ chỉ bắt đầu block được in ra

 

<div id = ‘print-area’>
<imgsrc = “{{Url(‘images/order_print.png’)}}”>
<divid = ‘print-area-dcinfo’>
<spanid = ‘print_area_dccode’>{{App\Helper\Helper::getFlpNo($orders[0]->FLPNo)}}</span><br/>
<spanid = ‘print_area_dcname’>{{$orders[0]->FamilyName}} {{$orders[0]->FirstName}}</span><br/>
<spanid = ‘print_area_address’>{{$orders[0]->ContactAddress}}</span><br/>
<spanid = ‘print_area_payment’></span>
</div>
<divid=”print-area-dcinfo2″>
<spanid=”print_area_date”>{{date_format($date,”d/m/Y”)}}</span>
<spanid=”print_area_taxcode”></span>
</div>
@if (isset($sponsor))
<divid=”print-area-sponsor”>
<span>Mã số bảo trợ:&nbsp;&nbsp;&nbsp; {{App\Helper\Helper::getFlpNo($sponsor->FLPNo)}}</span><br/>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{$sponsor->FamilyName}} {{$sponsor->FirstName}}</span>
</div>
@endif
<divid = ‘print-area-product’>
<table>
<thead>
<tr>
<thwidth = ’30px’></th>
<thwidth = ’45px’></th>
<thwidth = ‘260px’></th>
<thwidth = ’45px’></th>
<thwidth = ’55px’></th>
<thwidth = ’85px’></th>
<thwidth = ’80px’></th>
<thwidth = ‘150px’></th>
</tr>
</thead>
<tbody>
<?php
$totalCC = 0;
$totalAmount = 0;
if(count($orders) > 0) {
$row = 1;
foreach($orders as $order) {
?>
<tr>
<!–No–>
<td>{{$row}}</td>
<!–Code–>
<td>{{$order->ProductCode}}</td>
<!–Description–>
<tdclass=”product-span text-center”>{{$order->PVietnameseName}}</td>
<!–Unit–>
<tdclass=”product-span text-center”>{{$order->VietnameseName}}</td>
<!–Quantity–>
<tdclass=”product-span text-center”>{{$order->Quantity}}</td>
<!–Unit price–>
<tdclass=”product-span text-right”>{{number_format($order->UnitPrice)}}</td>
<!–CC–>
<tdclass=”product-span text-right”>{{$order->CC}}</td>
<tdclass=”product-span text-right”>{{number_format($order->Amount)}}
</td>
</tr>
<?php
$totalCC+=$order->CC;
$totalAmount+=$order->Amount;
$row++;
}
}
?>
</tbody>
</table>
</div>
<divid = ‘print-area-total’>
<span>{{$totalCC}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>{{number_format($totalAmount)}}</span><br/>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{number_format($totalAmount*0.1)}}</span><br/>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{number_format(($totalAmount*0.1)+$totalAmount)}}</span>
</div>
<divid = ‘print-area-moneytext’>
<span>
{{App\Helper\Helper::convert_number_to_words(($totalAmount*0.1)+$totalAmount)}}
</span>
</div>
<divid = ‘print-area-vat’>
<span>
10%
</span>
</div>
</div>
 
file css:
.location_container {
width:100%;
border-bottom: 1pxsolidblack;
margin-bottom: 20px;
}
.print-btn {
width:170px;
margin-right: 10px;
}
.form-control {
width:220px!important;
}
#printOrderButton, #printOrderButton2, #btnAddNewOrder {
display:none;
}
#print-area {
position: relative;
/* border:1px solid black; */
}
#print-area-dcinfo {
/* left tru di 15 cho tat ca */
position: absolute;
top:132px;
left:65px;
text-align: left;
}
#print-area-dcinfo span {
text-align: left;
line-height: 1.75em;
}
#print_area_address {
width: 300px;
word-break: break-word;
}
#print-area-dcinfo2 {
position: absolute;
top:146px;
left:605px;
}
#print-area-sponsor {
position: absolute;
top:200px;
left:465px;
}
#print-area-product{
position: absolute;
top:310px;
left:20px;
}
.product-span {
line-height: 1.50em;
}
#print-area-total {
position: absolute;
top:718px;
left:555px;
}
#print-area-total span{
line-height: 2em;
}
#print-area-moneytext {
position: absolute;
top:828px;
left:335px;
}
#print-area-vat {
position: absolute;
top:750px;
left:370px;
}
@media only screen and (max-width: 1280px){
.form-control {
width:200px!important;
font-size: 13px;
}
}
 

to-top