修改打印需求,并提供下载
This commit is contained in:
parent
128e3f9cea
commit
d50e080448
|
|
@ -22,10 +22,57 @@ class Printaction extends Base
|
||||||
protected $fontPath = 'public/tsf/jc.ttf'; // 请替换为你的字体文件路径
|
protected $fontPath = 'public/tsf/jc.ttf'; // 请替换为你的字体文件路径
|
||||||
|
|
||||||
// 显示条形码生成页面
|
// 显示条形码生成页面
|
||||||
public function print_device_barcode_index()
|
public function print_device_data_index()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$data = input();
|
||||||
|
if(array_key_exists('type',$data)){
|
||||||
|
return $this->print_device_data_index_action('down');
|
||||||
|
}else{
|
||||||
|
$result = $this->print_device_data_index_action('page');
|
||||||
|
$this->assign([
|
||||||
|
'data' => $result
|
||||||
|
]);
|
||||||
return $this->fetch();
|
return $this->fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function print_device_data_index_action($data){
|
||||||
|
$zengjie = Db::connect('zengjie_db');
|
||||||
|
$pc = $zengjie->table('box_code_all')->order('id desc')->find();
|
||||||
|
// dump($pc);
|
||||||
|
$sql = "SELECT
|
||||||
|
a.mac_code,
|
||||||
|
a.sn_code,
|
||||||
|
b.box_code,
|
||||||
|
FORMAT(b.box_num, '000') AS box_num
|
||||||
|
FROM
|
||||||
|
sn_code_all AS a
|
||||||
|
LEFT JOIN
|
||||||
|
box_code_all AS b ON a.batch_id = b.id
|
||||||
|
WHERE
|
||||||
|
a.batch_id IS NOT NULL
|
||||||
|
AND b.box_code = ?
|
||||||
|
ORDER BY
|
||||||
|
a.batch_id";
|
||||||
|
|
||||||
|
$result = $zengjie->query($sql, [$pc['box_code']]);
|
||||||
|
if($data == 'page'){
|
||||||
|
return $result;
|
||||||
|
}else{
|
||||||
|
$result2 = [
|
||||||
|
['Mac码','Sn码','箱号']
|
||||||
|
];
|
||||||
|
for ($i=0; $i < count($result); $i++) {
|
||||||
|
$result2[] = [$result[$i]['mac_code'],$result[$i]['sn_code'],$result[$i]['box_code'].'-'.$result[$i]['box_num']];
|
||||||
|
}
|
||||||
|
$excel = new \app\download\controller\Excel();
|
||||||
|
$excel->export($result2, $pc['box_code']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 显示外箱码生成页面
|
// 显示外箱码生成页面
|
||||||
public function print_outside_box_index()
|
public function print_outside_box_index()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,6 @@ class Savemsg extends Base{
|
||||||
|
|
||||||
];
|
];
|
||||||
protected $name_default = 0;
|
protected $name_default = 0;
|
||||||
protected $kitchenscale_db_msg = [
|
|
||||||
'cookbook'=>'app_user_cookbook',//菜谱表
|
|
||||||
'foodlist3'=>'app_z_national_standard_food_type_3',//食材列表3
|
|
||||||
'user'=>'app_user_data',//banner
|
|
||||||
];
|
|
||||||
|
|
||||||
// 加 bcadd(,,20)
|
// 加 bcadd(,,20)
|
||||||
// 减 bcsub(,,20)
|
// 减 bcsub(,,20)
|
||||||
|
|
@ -54,7 +49,7 @@ class Savemsg extends Base{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save_sn_msg($data = ['sn_code'=>'564654564654654','bl_name'=>'bl_5520']){
|
public function save_sn_msg($data = ['sn_code'=>'564654564654654','mac_code'=>'ce:sh:yo:ng:d1','bl_name'=>'bl_5520']){
|
||||||
try {
|
try {
|
||||||
// 你的业务逻辑
|
// 你的业务逻辑
|
||||||
if(count(input('post.')) > 0){
|
if(count(input('post.')) > 0){
|
||||||
|
|
@ -66,12 +61,18 @@ class Savemsg extends Base{
|
||||||
if(!array_key_exists('bl_name', $data)){
|
if(!array_key_exists('bl_name', $data)){
|
||||||
return $this->msg(10001);
|
return $this->msg(10001);
|
||||||
}
|
}
|
||||||
|
if(!array_key_exists('mac_code', $data)){
|
||||||
|
return $this->msg(10001);
|
||||||
|
}
|
||||||
if(!$this->verify_data_is_ok($data['sn_code'],'str')){
|
if(!$this->verify_data_is_ok($data['sn_code'],'str')){
|
||||||
return $this->msg(10005);
|
return $this->msg(10005);
|
||||||
}
|
}
|
||||||
if(!$this->verify_data_is_ok($data['bl_name'],'str')){
|
if(!$this->verify_data_is_ok($data['bl_name'],'str')){
|
||||||
return $this->msg(10005);
|
return $this->msg(10005);
|
||||||
}
|
}
|
||||||
|
if(!$this->verify_data_is_ok($data['mac_code'],'str')){
|
||||||
|
return $this->msg(10005);
|
||||||
|
}
|
||||||
$result = $this->save_sn_msg_action($data);
|
$result = $this->save_sn_msg_action($data);
|
||||||
return $result;
|
return $result;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
|
@ -217,6 +218,7 @@ class Savemsg extends Base{
|
||||||
$result = $zengjie->table('sn_code_all')->insert([
|
$result = $zengjie->table('sn_code_all')->insert([
|
||||||
'sn_code'=>$data['sn_code'],
|
'sn_code'=>$data['sn_code'],
|
||||||
'bluetooth_name'=>$data['bl_name'],
|
'bluetooth_name'=>$data['bl_name'],
|
||||||
|
'mac_code'=>$data['mac_code'],
|
||||||
'create_time'=>date('Y-m-d H:i:s'),
|
'create_time'=>date('Y-m-d H:i:s'),
|
||||||
]);
|
]);
|
||||||
if($result){
|
if($result){
|
||||||
|
|
@ -229,44 +231,79 @@ class Savemsg extends Base{
|
||||||
public function save_box_msg_action($data) {
|
public function save_box_msg_action($data) {
|
||||||
$zengjie = Db::connect('zengjie_db');
|
$zengjie = Db::connect('zengjie_db');
|
||||||
|
|
||||||
$box_num = $zengjie->table('box_code_all')->where(['box_code'=>$data['box_serial_number']])->count();
|
// 1. 检查sn_code_all中是否有重复数据
|
||||||
$box_num = $box_num+1;
|
$snCodes = explode(',', $data['sn_code_all']);
|
||||||
$result = $zengjie->table('box_code_all')->insert([
|
if (count($snCodes) !== count(array_unique($snCodes))) {
|
||||||
|
return $this->msg(10003, 'SN码列表中存在重复数据');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查这些SN码是否都存在于sn_code_all表中
|
||||||
|
$existCount = $zengjie->table('sn_code_all')
|
||||||
|
->where('sn_code', 'in', $snCodes)
|
||||||
|
->count();
|
||||||
|
|
||||||
|
if ($existCount !== count($snCodes)) {
|
||||||
|
return $this->msg(10004, '存在未登记的SN码');
|
||||||
|
}
|
||||||
|
Db::startTrans();
|
||||||
|
try{
|
||||||
|
$count = $zengjie->table('box_code_all')
|
||||||
|
->where(['box_code'=>$data['box_serial_number']])
|
||||||
|
->count();
|
||||||
|
$num = $count + 1;
|
||||||
|
|
||||||
|
$box_id = $zengjie->table('box_code_all')->insertGetId([
|
||||||
'box_code' => $data['box_serial_number'],
|
'box_code' => $data['box_serial_number'],
|
||||||
'box_num'=>$box_num,
|
'box_num' => $num,
|
||||||
'create_time' => date('Y-m-d H:i:s'),
|
'create_time' => date('Y-m-d H:i:s'),
|
||||||
'content_str' => $data['sn_code_all'],
|
'content_str' => $data['sn_code_all'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if($result){
|
$affectedRows = $zengjie->table('sn_code_all')
|
||||||
return $this->msg([]);
|
->where('sn_code', 'in', $snCodes)
|
||||||
}else{
|
->update(['batch_id' => $box_id]);
|
||||||
return $this->msg(10002,'录入失败');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 检查更新是否影响了预期的行数
|
||||||
|
if ($affectedRows !== count($snCodes)) {
|
||||||
|
throw new \Exception('更新SN码数量不匹配');
|
||||||
|
}
|
||||||
|
Db::commit();
|
||||||
|
return $this->msg(['id'=>$box_id]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// 回滚事务
|
||||||
|
Db::rollback();
|
||||||
|
return $this->msg(10002, '录入失败: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
// // 显式事务控制
|
||||||
|
// $zengjie->startTrans();
|
||||||
// try {
|
// try {
|
||||||
// // 使用事务闭包,TP5会自动管理事务
|
// $count = $zengjie->table('box_code_all')
|
||||||
// $result = $zengjie->transaction(function() use ($zengjie, $data) {
|
// ->where(['box_code'=>$data['box_serial_number']])
|
||||||
// $sn_code = $zengjie->table('box_code_all')->where(['box_code'=>$data['box_serial_number']])->count();
|
// ->count();
|
||||||
// $num = $sn_code+1;
|
// $num = $count + 1;
|
||||||
|
|
||||||
// $box_id = $zengjie->table('box_code_all')->insertGetId([
|
// $box_id = $zengjie->table('box_code_all')->insertGetId([
|
||||||
// 'box_code' => $data['box_serial_number'],
|
// 'box_code' => $data['box_serial_number'],
|
||||||
// 'box_num' => $num,
|
// 'box_num' => $num,
|
||||||
// 'create_time' => date('Y-m-d H:i:s'),
|
// 'create_time' => date('Y-m-d H:i:s'),
|
||||||
|
// 'content_str' => $data['sn_code_all'],
|
||||||
// ]);
|
// ]);
|
||||||
|
|
||||||
// // 使用安全的参数绑定方式
|
// $affectedRows = $zengjie->table('sn_code_all')
|
||||||
// $snCodes = explode(',', $data['sn_code_all']);
|
|
||||||
// $zengjie->table('sn_code_all')
|
|
||||||
// ->where('sn_code', 'in', $snCodes)
|
// ->where('sn_code', 'in', $snCodes)
|
||||||
// ->update(['batch_id' => $box_id]);
|
// ->update(['batch_id' => $box_id]);
|
||||||
|
|
||||||
// return $box_id;
|
// // 检查更新是否影响了预期的行数
|
||||||
// });
|
// if ($affectedRows !== count($snCodes)) {
|
||||||
|
// throw new \Exception('更新SN码数量不匹配');
|
||||||
|
// }
|
||||||
|
|
||||||
// return $this->msg(['id'=>$result]);
|
// $zengjie->commit();
|
||||||
|
// return $this->msg(['id'=>$box_id]);
|
||||||
// } catch (\Exception $e) {
|
// } catch (\Exception $e) {
|
||||||
|
// if ($zengjie->getPdo()->inTransaction()) {
|
||||||
|
// $zengjie->rollback();
|
||||||
|
// }
|
||||||
// trace('保存盒信息失败: ' . $e->getMessage(), 'error');
|
// trace('保存盒信息失败: ' . $e->getMessage(), 'error');
|
||||||
// return $this->msg(10002, '录入失败: ' . $e->getMessage());
|
// return $this->msg(10002, '录入失败: ' . $e->getMessage());
|
||||||
// }
|
// }
|
||||||
|
|
@ -302,4 +339,60 @@ class Savemsg extends Base{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
######################################################测试#########################################################
|
||||||
|
######################################################测试#########################################################
|
||||||
|
######################################################测试#########################################################
|
||||||
|
|
||||||
|
public function ceshiyong(){
|
||||||
|
// // 添加测试一维码数据
|
||||||
|
// $data = [];
|
||||||
|
// for ($i = 0; $i < 500; $i++) {
|
||||||
|
// // 生成15位随机数字作为sn_code
|
||||||
|
// $sn_code = '';
|
||||||
|
// for ($j = 0; $j < 15; $j++) {
|
||||||
|
// $sn_code .= mt_rand(0, 9);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 生成随机的MAC地址
|
||||||
|
// $mac_parts = [];
|
||||||
|
// for ($k = 0; $k < 6; $k++) {
|
||||||
|
// $mac_parts[] = sprintf('%02x', mt_rand(0, 255));
|
||||||
|
// }
|
||||||
|
// $mac_code = implode(':', $mac_parts);
|
||||||
|
|
||||||
|
// // 构建数据数组
|
||||||
|
// $data[] = [
|
||||||
|
// 'sn_code' => $sn_code,
|
||||||
|
// 'mac_code' => $mac_code,
|
||||||
|
// 'create_time' => date('Y-m-d H:i:s'),
|
||||||
|
// 'is_print' => 1,
|
||||||
|
// 'bluetooth_name' => 'bl_5520'
|
||||||
|
// ];
|
||||||
|
// }
|
||||||
|
// $zengjie = Db::connect('zengjie_db');
|
||||||
|
// $result = $zengjie->table('sn_code_all')->insertAll($data);
|
||||||
|
// dump($result);
|
||||||
|
// die;
|
||||||
|
// // 添加测试一维码数据
|
||||||
|
|
||||||
|
// 添加测试打包数据
|
||||||
|
$zengjie = Db::connect('zengjie_db');
|
||||||
|
$records = $zengjie->table('sn_code_all')
|
||||||
|
->where('batch_id', 'null') // 或者使用 ->whereNull('batch_id')
|
||||||
|
->orderRaw('NEWID()') // SQL Server的随机排序函数
|
||||||
|
->limit(10)
|
||||||
|
->select();
|
||||||
|
$data['sn_code_all'] = [];
|
||||||
|
$data['box_serial_number'] = '3ST011527003';
|
||||||
|
for ($i=0; $i < count($records); $i++) {
|
||||||
|
$data['sn_code_all'][] = $records[$i]['sn_code'];
|
||||||
|
}
|
||||||
|
$data['sn_code_all'] = implode(',',$data['sn_code_all']);
|
||||||
|
$result = $this->save_box_msg_action($data);
|
||||||
|
dump($result);
|
||||||
|
dump($data);
|
||||||
|
// 添加测试打包数据
|
||||||
|
// return $data;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>标签打印系统</title>
|
|
||||||
<script src="../x_admin/js/jq.js"></script>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 20px;
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
background-color: white;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
font-size: 16px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#barcodeContainer {
|
|
||||||
margin: 20px auto;
|
|
||||||
padding: 10px;
|
|
||||||
border: 2px dashed black;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#barcodeImage {
|
|
||||||
width: 600px;
|
|
||||||
height: 200px;
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
/* border: 1px solid red; */
|
|
||||||
}
|
|
||||||
|
|
||||||
#printBtn {
|
|
||||||
display: block;
|
|
||||||
width: 200px;
|
|
||||||
margin: 20px auto;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: #1E88E5;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media print {
|
|
||||||
body * {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
#barcodeContainer, #barcodeContainer * {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
#barcodeContainer {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>标签打印系统</h1>
|
|
||||||
<div class="description">440×147px图片打印到60×20mm标签纸</div>
|
|
||||||
|
|
||||||
<div id="barcodeContainer">
|
|
||||||
<img id="barcodeImage" src="">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button id="printBtn" onclick="dayin()">直接打印</button>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
loadBarcode();
|
|
||||||
|
|
||||||
// $('#printBtn').click(function() {
|
|
||||||
// window.print();
|
|
||||||
// });
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadBarcode() {
|
|
||||||
console.log(Date.now)
|
|
||||||
$.ajax({
|
|
||||||
url: "/z/print_device_barcode",
|
|
||||||
type: "POST",
|
|
||||||
dataType: "json",
|
|
||||||
success: function(response) {
|
|
||||||
if(response.code == 10002) {
|
|
||||||
setTimeout(loadBarcode, 1000);
|
|
||||||
}
|
|
||||||
else if(response.code == 10003) {
|
|
||||||
alert(response.msg);
|
|
||||||
}
|
|
||||||
else if(response.data) {
|
|
||||||
$('#barcodeImage').attr('src', response.data.image);
|
|
||||||
// setTimeout(() => {
|
|
||||||
// dayin()
|
|
||||||
// }, 500);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(xhr, status, error) {
|
|
||||||
console.error("请求出错:", error);
|
|
||||||
setTimeout(loadBarcode, 3000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function dayin(){
|
|
||||||
window.print();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>最近一次打印数据</title>
|
||||||
|
<script src="../x_admin/js/jq.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0 0;
|
||||||
|
padding: 0 0;
|
||||||
|
}
|
||||||
|
.big_box{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.down{
|
||||||
|
height: 30px;
|
||||||
|
width: 100px;
|
||||||
|
line-height: 30px;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid black;
|
||||||
|
box-shadow: 1px 1px 1px;
|
||||||
|
margin-left: 10px;
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="big_box">
|
||||||
|
<table border="1" cellpadding="5">
|
||||||
|
<tr>
|
||||||
|
<th>MAC地址</th>
|
||||||
|
<th>SN码</th>
|
||||||
|
<th>箱号</th>
|
||||||
|
</tr>
|
||||||
|
{volist name="data" id="item"}
|
||||||
|
<tr>
|
||||||
|
<td>{$item.mac_code|default='未分配'}</td>
|
||||||
|
<td>{$item.sn_code}</td>
|
||||||
|
<td>{$item.box_code}-{$item.box_num}</td>
|
||||||
|
</tr>
|
||||||
|
{/volist}
|
||||||
|
</table>
|
||||||
|
<div class="down">点击下载</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$('.down').on('click',function(){
|
||||||
|
// $.ajax({
|
||||||
|
// url:"print_device_data_index_action", //请求的url地址
|
||||||
|
// dataType:"json", //返回格式为json
|
||||||
|
// async:true,//请求是否异步,默认为异步,这也是ajax重要特性
|
||||||
|
// data:{"id":"value"}, //参数值
|
||||||
|
// type:"POST", //请求方式
|
||||||
|
// beforeSend:function(){
|
||||||
|
// //请求前的处理
|
||||||
|
// },
|
||||||
|
// success:function(req){
|
||||||
|
// //请求成功时处理
|
||||||
|
// },
|
||||||
|
// complete:function(){
|
||||||
|
// //请求完成的处理
|
||||||
|
// },
|
||||||
|
// error:function(){
|
||||||
|
// //请求出错处理
|
||||||
|
// }});
|
||||||
|
// window.open('https://www.example.com', '_blank');
|
||||||
|
window.location.href('https://tc.pcxbc.com/z/print_device_data_index_action?type=down');
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,205 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\download\controller;
|
||||||
|
|
||||||
|
use think\Controller;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||||||
|
|
||||||
|
class Excel extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
// public function exportWithCustomStyle()
|
||||||
|
// {
|
||||||
|
// $data = [
|
||||||
|
// ['订单号', '客户名称', '订单金额', '下单日期', '状态'],
|
||||||
|
// ['ORD20230001', '张三', 1580.00, '2023-05-10', '已完成'],
|
||||||
|
// ['ORD20230002', '李四', 2399.00, '2023-05-11', '已发货'],
|
||||||
|
// ['ORD20230003', '王五', 899.00, '2023-05-12', '待付款'],
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// $options = [
|
||||||
|
// 'sheet_title' => '五月订单', // 工作表名称
|
||||||
|
// 'header_style' => [
|
||||||
|
// 'font' => [
|
||||||
|
// 'bold' => true,
|
||||||
|
// 'color' => ['argb' => 'FFFFFFFF'] // 白色文字
|
||||||
|
// ],
|
||||||
|
// 'fill' => [
|
||||||
|
// 'fillType' => Fill::FILL_SOLID,
|
||||||
|
// 'startColor' => ['argb' => 'FF0070C0'] // 蓝色背景
|
||||||
|
// ],
|
||||||
|
// 'alignment' => [
|
||||||
|
// 'horizontal' => Alignment::HORIZONTAL_CENTER,
|
||||||
|
// ],
|
||||||
|
// ],
|
||||||
|
// 'stripe_color1' => 'FFE6F1FF', // 浅蓝色
|
||||||
|
// 'stripe_color2' => 'FFD6E6FF', // 稍深一点的蓝色
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// $excel = new \app\download\controller\Excel();
|
||||||
|
// $excel->export($data, '五月订单报表', $options);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出 Excel 文件(带斑马纹效果)
|
||||||
|
*
|
||||||
|
* @param array $data 要导出的数据,格式为二维数组,第一行为表头
|
||||||
|
* @param string $filename 下载的文件名(不带扩展名)
|
||||||
|
* @param array $options 可选配置项
|
||||||
|
* - 'sheet_title' => string 工作表标题
|
||||||
|
* - 'header_style' => array 自定义表头样式
|
||||||
|
* - 'content_style' => array 自定义内容样式
|
||||||
|
* - 'zebra_stripe' => bool 是否启用斑马纹效果(默认true)
|
||||||
|
* - 'stripe_color1' => string 斑马纹第一种颜色(默认白色)
|
||||||
|
* - 'stripe_color2' => string 斑马纹第二种颜色(默认浅灰色)
|
||||||
|
* - 'auto_width' => bool 是否自动调整列宽
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function export(array $data, string $filename = 'export', array $options = [])
|
||||||
|
{
|
||||||
|
// 验证数据
|
||||||
|
if (empty($data) || !is_array($data) || !is_array($data[0])) {
|
||||||
|
throw new \InvalidArgumentException('导出数据格式不正确,应为二维数组且第一行为表头');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认配置
|
||||||
|
$defaultOptions = [
|
||||||
|
'sheet_title' => 'Sheet1',
|
||||||
|
'header_style' => [
|
||||||
|
'font' => ['bold' => true],
|
||||||
|
'fill' => [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['argb' => Color::COLOR_YELLOW],
|
||||||
|
],
|
||||||
|
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER],
|
||||||
|
'borders' => [
|
||||||
|
'outline' => ['borderStyle' => Border::BORDER_THIN],
|
||||||
|
'inside' => ['borderStyle' => Border::BORDER_THIN]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'content_style' => [
|
||||||
|
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER],
|
||||||
|
'borders' => [
|
||||||
|
'outline' => ['borderStyle' => Border::BORDER_THIN],
|
||||||
|
'inside' => ['borderStyle' => Border::BORDER_THIN]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'zebra_stripe' => true, // 默认启用斑马纹
|
||||||
|
'stripe_color1' => 'FFFFFFFF', // 白色
|
||||||
|
'stripe_color2' => 'FFEEEEEE', // 浅灰色
|
||||||
|
'auto_width' => true,
|
||||||
|
];
|
||||||
|
|
||||||
|
// 合并用户配置和默认配置
|
||||||
|
$options = array_merge($defaultOptions, $options);
|
||||||
|
|
||||||
|
// 创建 Spreadsheet 对象
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setTitle($options['sheet_title']);
|
||||||
|
|
||||||
|
// 获取列数和行数
|
||||||
|
$columnCount = count($data[0]);
|
||||||
|
$rowCount = count($data);
|
||||||
|
|
||||||
|
// 写入数据
|
||||||
|
foreach ($data as $rowIndex => $rowData) {
|
||||||
|
for ($colIndex = 0; $colIndex < $columnCount; $colIndex++) {
|
||||||
|
$sheet->setCellValueByColumnAndRow($colIndex + 1, $rowIndex + 1, $rowData[$colIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置表头样式
|
||||||
|
$headerRange = 'A1:' . $this->getExcelColumnName($columnCount) . '1';
|
||||||
|
$sheet->getStyle($headerRange)->applyFromArray($options['header_style']);
|
||||||
|
|
||||||
|
// 设置内容样式
|
||||||
|
$contentRange = 'A2:' . $this->getExcelColumnName($columnCount) . $rowCount;
|
||||||
|
$sheet->getStyle($contentRange)->applyFromArray($options['content_style']);
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
// 重点:斑马纹效果实现
|
||||||
|
// =============================================
|
||||||
|
if ($options['zebra_stripe']) {
|
||||||
|
$this->applyZebraStripe(
|
||||||
|
$sheet,
|
||||||
|
$columnCount,
|
||||||
|
$rowCount,
|
||||||
|
$options['stripe_color1'],
|
||||||
|
$options['stripe_color2']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动调整列宽
|
||||||
|
if ($options['auto_width']) {
|
||||||
|
for ($colIndex = 1; $colIndex <= $columnCount; $colIndex++) {
|
||||||
|
$sheet->getColumnDimensionByColumn($colIndex)->setAutoSize(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置响应头以触发文件下载
|
||||||
|
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||||
|
header('Content-Disposition: attachment;filename="' . $filename . '.xlsx"');
|
||||||
|
header('Cache-Control: max-age=0');
|
||||||
|
|
||||||
|
// 保存并输出 Excel 文件
|
||||||
|
$writer = new Xlsx($spreadsheet);
|
||||||
|
$writer->save('php://output');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用斑马纹效果(核心实现)
|
||||||
|
*
|
||||||
|
* @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet
|
||||||
|
* @param int $columnCount 总列数
|
||||||
|
* @param int $totalRows 总行数(包括表头)
|
||||||
|
* @param string $color1 第一种颜色
|
||||||
|
* @param string $color2 第二种颜色
|
||||||
|
*/
|
||||||
|
protected function applyZebraStripe($sheet, $columnCount, $totalRows, $color1, $color2)
|
||||||
|
{
|
||||||
|
// 从第二行开始应用斑马纹(跳过表头)
|
||||||
|
for ($rowIndex = 2; $rowIndex <= $totalRows; $rowIndex++) {
|
||||||
|
// 计算当前行应该使用哪种颜色
|
||||||
|
$color = ($rowIndex % 2 == 0) ? $color1 : $color2;
|
||||||
|
|
||||||
|
// 设置行样式
|
||||||
|
$rowStyle = [
|
||||||
|
'fill' => [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['argb' => $color],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// 应用样式到整行
|
||||||
|
$range = 'A' . $rowIndex . ':' . $this->getExcelColumnName($columnCount) . $rowIndex;
|
||||||
|
$sheet->getStyle($range)->applyFromArray($rowStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Excel 列名
|
||||||
|
*
|
||||||
|
* @param int $index 列索引(从1开始)
|
||||||
|
* @return string Excel 列名
|
||||||
|
*/
|
||||||
|
protected function getExcelColumnName($index)
|
||||||
|
{
|
||||||
|
$columnName = '';
|
||||||
|
while ($index > 0) {
|
||||||
|
$remainder = ($index - 1) % 26;
|
||||||
|
$columnName = chr(65 + $remainder) . $columnName;
|
||||||
|
$index = intval(($index - 1) / 26);
|
||||||
|
}
|
||||||
|
return $columnName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -606,11 +606,13 @@ Route::any('/k/a/cookbook/stop_and_run', 'app/kitchenscale/admin.cookbook/stop_a
|
||||||
Route::any('/z/config_msg', 'app/ZengJieCode/app.savemsg/config_msg');
|
Route::any('/z/config_msg', 'app/ZengJieCode/app.savemsg/config_msg');
|
||||||
Route::any('/z/save_sn_msg', 'app/ZengJieCode/app.savemsg/save_sn_msg');
|
Route::any('/z/save_sn_msg', 'app/ZengJieCode/app.savemsg/save_sn_msg');
|
||||||
Route::any('/z/save_box_msg', 'app/ZengJieCode/app.savemsg/save_box_msg');
|
Route::any('/z/save_box_msg', 'app/ZengJieCode/app.savemsg/save_box_msg');
|
||||||
|
// 测试用
|
||||||
|
Route::any('/z/ceshiyong', 'app/ZengJieCode/app.savemsg/ceshiyong');
|
||||||
// 重新打印
|
// 重新打印
|
||||||
Route::any('/z/print_again', 'app/ZengJieCode/app.savemsg/print_again');
|
Route::any('/z/print_again', 'app/ZengJieCode/app.savemsg/print_again');
|
||||||
|
|
||||||
Route::any('/z/print_device_barcode_index', 'app/ZengJieCode/admin.printaction/print_device_barcode_index');
|
Route::any('/z/print_device_data_index', 'app/ZengJieCode/admin.printaction/print_device_data_index');
|
||||||
Route::any('/z/print_outside_box_index', 'app/ZengJieCode/admin.printaction/print_outside_box_index');
|
// Route::any('/z/print_outside_box_index', 'app/ZengJieCode/admin.printaction/print_outside_box_index');
|
||||||
|
|
||||||
// 获取蓝牙录入的未打印条码
|
// 获取蓝牙录入的未打印条码
|
||||||
Route::any('/z/print_device_barcode', 'app/ZengJieCode/admin.printaction/print_device_barcode');
|
Route::any('/z/print_device_barcode', 'app/ZengJieCode/admin.printaction/print_device_barcode');
|
||||||
|
|
@ -619,6 +621,8 @@ Route::any('/z/print_scan_barcode', 'app/ZengJieCode/admin.printaction/print_sca
|
||||||
// 获取大箱没打印的条码
|
// 获取大箱没打印的条码
|
||||||
Route::any('/z/print_combined_code', 'app/ZengJieCode/admin.printaction/print_combined_code');
|
Route::any('/z/print_combined_code', 'app/ZengJieCode/admin.printaction/print_combined_code');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
################################################################下面是设备入库录入################################################################
|
################################################################下面是设备入库录入################################################################
|
||||||
################################################################################################################################################
|
################################################################################################################################################
|
||||||
// 默认配置
|
// 默认配置
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue