$taskId ] ); } /** * */ public function init() { parent::init(); $this->isRemote = \Yii::$app->params['isRemoteUpload']; } /** * 生成复杂的路径 * @return string */ public function pathCreator(...$params) { $hash = md5(implode('_', $params)); $first = substr($hash, 0, 3); $second = substr($hash, 3, 2); $dir = $first . __DS__ . $second . __DS__; return $dir; } /** * 获取文件名 * @return string|null * @throws \Exception */ public function getFileName($ext = '.csv') { $this->fileName = date('YmdHis', Date::nowTime()) . random_int(1000, 9999) . $ext; return $this->fileName; } /** * 获取保存的路径 * @return array|null */ public function getSavePath() { $this->savePath = $this->pathCreator(date('Ymd', Date::nowTime())); return trim((string)$this->savePath, __DS__); } /** * @return bool|string|null */ public function getSaveBasePath() { $this->saveBasePath = Yii::getAlias('@backendApi') . __DS__ . 'web' . __DS__ . 'upload' . __DS__ . (isset(\Yii::$app->params['excelLocalDir']) ? \Yii::$app->params['excelLocalDir'] : ''); return trim((string)$this->saveBasePath, __DS__); } /** * 创建目录(递归创建) * * @param $dir * @return string|false */ public function mkdir($dir) { if (!is_dir($dir)) { $this->mkdir(dirname($dir)); if (!mkdir($dir, 0777)) return false; @exec('chown -R www:www /'.$dir); @exec('chmod -R 777 /'.$dir); } return $dir; } /** * @return array|mixed */ public function getParams() { $this->params = CacheHelper::getAsyncParams($this->taskId); // 设置语言 Yii::$app->language = $this->params['language'] ?? 'en-US'; Yii::$app->sourceLanguage = Yii::$app->language == 'zh-CN' ? 'en-US' : 'zh-CN'; return $this->params; } /** * @return mixed|null */ public function getUserId() { $this->userId = isset($this->params['userId']) ? $this->params['userId'] : null; return $this->userId; } /** * @return |null */ public function getExportId() { $this->exportId = isset($this->params['exportId']) ? $this->params['exportId'] : null; return $this->userId; } /** * 生成 * @return bool * @throws Exception * @throws InvalidConfigException * @throws \yii\httpclient\Exception */ public function generate() { $this->getParams(); if (!$this->params) { throw new Exception('无法获取需要的参数'); } $path = $this->getSaveBasePath() . __DS__ . $this->getSavePath(); $path = __DS__ . $path; $realFile = $this->mkdir($path) . __DS__ . $this->getFileName(); $this->completed = false; $this->getExportId(); $this->getUserId(); $fileNameUpdated = false; $this->_fp = fopen($realFile, 'w'); @exec('chown -R www:www /'.$realFile); @exec('chmod -R 777 /'.$realFile); // 获取列表数据及表头 $this->_listModel = new $this->listModelClass(); $this->_listModel->isExport = true; if(method_exists($this->_listModel, 'getExportHeaders')){ if(method_exists($this->_listModel, 'exportPrepare')) {//导出数据提前设置参数 $this->_listModel->exportPrepare(['condition' => $this->params['condition'], 'params' => $this->params['params'], 'others' => isset($this->params['others']) ? $this->params['others'] : [], 'page' => 0, 'pageSize' => $this->pageSize, 'userId' => $this->userId]); } $headers = $this->_listModel->getExportHeaders($this->userId); fputcsv($this->_fp, $headers); unset($headers); $this->_updateFirst($realFile, 1); } else { throw new Exception($this->listModelClass.'的getExportHeaders方法不存在'); } $this->_loopWriteData($realFile, $fileNameUpdated); $this->complete(); return true; } /** * 循环写入数据 * @param $realFile * @param $fileNameUpdated * @param int $page * @param int $counter * @return string * @throws Exception */ private function _loopWriteData($realFile, &$fileNameUpdated, $page = 0, $counter = 0){ if(method_exists($this->_listModel, 'getList')){ $list = $this->_listModel->getList(['condition'=>$this->params['condition'], 'params'=> $this->params['params'] ?? [], 'others'=> $this->params['others'] ?? [], 'page'=>$page, 'pageSize'=>$this->pageSize, 'userId'=>$this->userId]); } else { throw new Exception($this->listModelClass.'的getList方法不存在'); } if($page >= $list['totalPages']){ return 'finish'; } if(!empty($list['list'])){ foreach($list['list'] as $columnData){ fputcsv($this->_fp, Tool::arrTextConvert($columnData)); $counter++; if ($list['totalCount'] < $counter) { // $counter = $list['totalCount']; return 'finish'; } $percent = intval(($counter / $list['totalCount']) * 100); $this->_updatePercent($percent); // if (!$fileNameUpdated) { // $this->_updateFirst($realFile, $percent); // } else { // $this->_updatePercent($percent); // } // $fileNameUpdated = true; unset($percent, $columnData); } $page++; unset($list); return $this->_loopWriteData($realFile, $fileNameUpdated, $page, $counter); } unset($list); return 'finish'; } /** * 循环写入数据 */ private function _loopWriteDataOrder() { $orderQuery = Order::find() ->alias('O') ->where($this->params['condition'], $this->params['params']) ->select('O.*,U.REAL_NAME,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV,OG.STANDARD_PRICE') ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); // 订单中间表只查询待支付和支付失败的订单 $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value']; // 待支付 $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value']; // 支付失败 $orderStandardQuery = ApproachOrder::find() ->alias('O') ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params']) ->select('O.*,U.REAL_NAME,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV,OG.STANDARD_PRICE') ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', ApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); $queryAll = $orderQuery->union($orderStandardQuery, true); $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]); $lists = $query->all(); if(!empty($lists)){ $regionConfig = Cache::getRegionConfig(); foreach($lists as $columnData) { $CREATE_USER_ID = Info::getUserIdByUserName($columnData['CREATE_USER']); $createUserName = Info::getUserRealNameByUserId($CREATE_USER_ID); $columnAccept = [ 'USER_NAME' => $columnData['USER_NAME'], 'DEC_USER_NAME' => $columnData['DEC_USER_ID'], 'CREATE_USER' => $columnData['CREATE_USER'], 'CREATE_USER_NAME' => $createUserName, 'SN' => $columnData['SN'], 'STATUS' => Tool::paramConvert(\Yii::$app->params['orderStatus'])[$columnData['STATUS']]['label'] ?? '', 'SKU_CODE' => $columnData['SKU_CODE'], 'GOODS_TITLE' => Tool::mbSignConvert($columnData['GOODS_TITLE']) , 'CONSIGNEE' => $columnData['CONSIGNEE'], 'MOBILE' => "\t{$columnData['MOBILE']}", 'TEL' => "\t{$columnData['TEL']}", 'PROVINCE' => $regionConfig[$columnData['PROVINCE']]['REGION_NAME'] ?? '', 'CITY' => $regionConfig[$columnData['CITY']]['REGION_NAME'] ?? '', 'COUNTY' => $regionConfig[$columnData['COUNTY']]['REGION_NAME'] ?? '', 'ADDRESS' => $columnData['ADDRESS'], 'PERIOD_NUM' => $columnData['PERIOD_NUM'], 'ORDER_TYPE' => ($columnData['ORDER_TYPE'] == 'ZC') ? 'Welcome pack' : (in_array($columnData['PAY_TYPE'], ['cash', 'pay_stack']) ? 'Repeat Purchase': 'Points'), // 'WAREHOUSE' => $columnData['WAREHOUSE'], 'CREATED_AT' => Date('Y-m-d H:i:s', $columnData['CREATED_AT']), 'PAY_TYPE' => ShopGoods::payTypes()[$columnData['PAY_TYPE']]['name'] ?? ShopGoods::payTypes()['cash']['name'], 'PAY_AT' => $columnData['PAY_AT'] > 0 ? Date('Y-m-d H:i:s', $columnData['PAY_AT']) : '', 'DELIVERY_AT' => $columnData['DELIVERY_AT'] > 0 ? Date('Y-m-d H:i:s', $columnData['DELIVERY_AT']) : '', 'BUY_NUMS' => $columnData['BUY_NUMS'], 'REAL_PRICE' => $columnData['REAL_PRICE'], 'TOTAL_PRICE' => $columnData['REAL_PRICE'] * $columnData['BUY_NUMS'], 'REAL_PV' => $columnData['REAL_PV'] * $columnData['BUY_NUMS'], 'STANDARD_PRICE' => $columnData['STANDARD_PRICE'] * $columnData['BUY_NUMS'], 'PAY_FREIGHT' => $columnData['PAY_FREIGHT'], 'TAX_RATE' => $columnData['TAX_RATE'], 'TAX_AMOUNT' => Tool::calculateTax($columnData['REAL_PRICE'], $columnData['TAX_RATE'], $columnData['BUY_NUMS']), 'EXPRESS_COMPANY' => $columnData['EXPRESS_COMPANY'], 'ORDER_TRACK_NO' => $columnData['ORDER_TRACK_NO'], 'EXPRESS_TYPE' => $columnData['EXPRESS_TYPE'] == 0 ? 'mailing ':' auto pick', 'FRONT_REMARK' => $columnData['FRONT_REMARK'], 'DELIVERY_STATUS_NAME' => Tool::paramConvert(\Yii::$app->params['deliveryStatus'])[$columnData['DELIVERY_STATUS']]['label'] ?? '', 'IS_AUTO' => $columnData['IS_AUTO'] == 1 ? 'Yes' : 'No', ]; fputcsv($this->_fp, Tool::arrTextConvert($columnAccept)); unset($percent, $columnData, $columnAccept); } unset($list); } unset($list); return 'finish'; } /** * 完成 * @return bool * @throws Exception * @throws InvalidConfigException * @throws \yii\httpclient\Exception */ public function complete() { $this->_updatePercent(100); if ($this->completed) { return true; } if ($this->_fp) { fclose($this->_fp); } // 把导出的文件上传至静态文件服务器 if ($this->isRemote) { $realFile = $this->getSaveBasePath() . __DS__ . $this->getSavePath() . __DS__ . $this->getFileName(); $remoteUploadApi = RemoteUploadApi::instance(); if ($uploadResult = $remoteUploadApi->upload($realFile)) { Export::updateAll(['REMOTE_URL' => $uploadResult['url'], 'IS_EXPORTING' => 0, 'EXPORT_PERCENT' => 100, 'ENDED_AT' => Date::nowTime()], 'ID=:ID', [':ID' => $this->exportId]); } else { $this->_errorHandle(); throw new Exception('文件远程上传失败'); } // 删除本地临时文件 unlink($realFile); } else { Export::updateAll(['IS_EXPORTING' => 0, 'EXPORT_PERCENT' => 100, 'ENDED_AT' => Date::nowTime()], 'ID=:ID', [':ID' => $this->exportId]); } \Yii::$app->swooleAsyncTimer->pushAsyncPercentToAdmin(100, ['MODEL' => 'EXPORT', 'ID' => $this->exportId, 'FIELD' => 'EXPORT_PERCENT']); CacheHelper::deleteAsyncParams($this->taskId); $this->completed = true; } /** * @param $message */ private function _errorNotice($message) { Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($this->userId, $message, false); } /** * 首次更新 * @param $exportId * @param $realName */ private function _updateFirst($realName, $percent) { $fileName = str_replace($this->getSaveBasePath() . __DS__, '', $realName); Export::updateAll([ 'FILE_NAME' => str_replace(__DS__, '/', $fileName), 'UPDATED_AT' => Date::nowTime(), 'EXPORT_PERCENT' => $percent, ], 'ID=:ID', [':ID' => $this->exportId]); } /** * 更新百分比 * @param $exportId * @param $percent */ private function _updatePercent($percent) { // 把数据写入数据库中 Export::updateAll(['EXPORT_PERCENT' => $percent], 'ID=:ID', [':ID' => $this->exportId]); \Yii::$app->swooleAsyncTimer->pushAsyncPercentToAdmin($percent, ['MODEL' => 'EXPORT', 'ID' => $this->exportId, 'FIELD' => 'EXPORT_PERCENT']); } /** * 发生错误处理 * @param $exportId */ private function _errorHandle() { Export::updateAll(['IS_EXPORTING' => 0], 'ID=:ID', [':ID' => $this->exportId]); } /** * 导出逻辑 * @param $filter * @param $listName * @param null $consoleRouter * @throws Exception */ public function exportHandle($filter, $listName, $consoleRouter = null){ $params = [ 'moduleId' => $this->moduleId, 'listName' => $listName, 'action' => $consoleRouter ? $consoleRouter : Yii::$app->controller->id.'/'.Yii::$app->controller->action->id, // 这里这么写,是因为调用的异步路由和同步的控制器和方法是一样的,所以,只要不传默认调和同步一样的异步方法 'userId' => Yii::$app->user->id, ]; $this->webToAsync($params,$filter); } /** * 页面到异步的请求 * @param $params * @param array $extend * @return bool * @throws Exception */ public function webToAsync($params, $extend = []) { $default = [ 'moduleId' => null, 'listName' => null, 'remark' => null, 'action' => null, 'userId' => null, ]; $params = Tool::deepParse($params, $default); if (!$params['moduleId'] || !$params['listName'] || !$params['action']) { throw new Exception('请设置moduleId,listName和action'); } // 把文件对应的相关资料存入数据库中 $export = new Export(); $export->EXPORT_NAME = $params['listName'] . '_' . date('Exp_y-m-d H:i:s', Date::nowTime()); $export->MODULE_NAME = $params['moduleId']; $export->REMARK = $params['remark']; $export->IS_EXPORTING = 1; $export->ADMIN_ID = \Yii::$app->user->id; $export->STARTED_AT = Date::nowTime(); $export->CREATED_AT = Date::nowTime(); $export->EXPORT_PERCENT = 0; $export->ENDED_AT = 0; $export->UPDATED_AT = 0; if (!$export->save()) { throw new Exception(Form::formatErrorsForApi($export->getErrors())); } $extend = array_merge($extend, [ 'exportId' => $export->ID, 'userId' => $params['userId'], 'language' => Yii::$app->language, ]); // 异步处理添加任务 $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle($params['action'], $extend); if($taskKey === false){ // 删除刚刚添加的导出数据 Export::deleteAll(['ID'=>$export->ID]); throw new Exception('导出失败,请求异步处理服务器失败'); } return $taskKey; } /** * 生成 * @return bool * @throws Exception * @throws InvalidConfigException * @throws \yii\httpclient\Exception */ public function generateOrderExcel() { $this->getParams(); if (!$this->params) { throw new Exception('无法获取需要的参数'); } $path = $this->getSaveBasePath() . __DS__ . $this->getSavePath(); $path = __DS__ . $path; $realFile = $this->mkdir($path) . __DS__ . $this->getFileName(); $this->completed = false; $this->getExportId(); $this->getUserId(); $fileNameUpdated = false; $this->_fp = fopen($realFile, 'w'); @exec('chown -R www:www /'.$realFile); @exec('chmod -R 777 /'.$realFile); // 获取列表数据及表头 $this->_listModel = new $this->listModelClass(); $this->_listModel->isExport = true; if(method_exists($this->_listModel, 'getExportHeaders')){ if(method_exists($this->_listModel, 'exportPrepare')) {//导出数据提前设置参数 $this->_listModel->exportPrepare(['condition' => $this->params['condition'], 'params' => $this->params['params'], 'others' => $this->params['others'] ?? [], 'page' => 0, 'pageSize' => 100000, 'userId' => $this->userId]); } $headers = $this->_listModel->getExportHeaders($this->userId); fputcsv($this->_fp, $headers); unset($headers); $this->_updateFirst($realFile, 1); } else { throw new Exception($this->listModelClass.'的getExportHeaders方法不存在'); } $this->_loopWriteDataOrder(); $this->complete(); return true; } /** * 生成 * @return bool * @throws Exception * @throws InvalidConfigException * @throws \yii\httpclient\Exception */ public function generateOrderPDF() { $this->getParams(); if (!$this->params) { throw new Exception('无法获取需要的参数'); } $path = __DS__ . $this->getSaveBasePath() . __DS__ . $this->getSavePath(); $realFile = $this->mkdir($path) . __DS__ . $this->getFileName('.pdf'); $this->completed = false; $this->getExportId(); $this->getUserId(); $fileNameUpdated = false; // 获取列表数据及表头 $this->_listModel = new $this->listModelClass(); $this->_listModel->isExport = true; // 查询订单数据 // $oderList = $this->_loopWriteDataPDF($realFile, $fileNameUpdated); $orderQuery = Order::find() ->alias('O') ->where($this->params['condition'], $this->params['params']) ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV') ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); // 订单中间表只查询待支付和支付失败的订单 $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value']; // 待支付 $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value']; // 支付失败 $orderStandardQuery = ApproachOrder::find() ->alias('O') ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params']) ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV') ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', ApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); $queryAll = $orderQuery->union($orderStandardQuery, true); $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]); $oderList = $query->all(); if ($oderList) { $userId = ''; $userName = ''; $address = ''; $mobile = ''; $orderAt = ''; $orderDetails = ''; $orderSn = ''; $orderAmount = 0; // 合计总额 $orderNums = 0; // 合计总数 $totalTaxAmount = 0; // 合计税额 $totalAmount = 0; foreach ($oderList as $key => $value) { $provinceName = $value['PROVINCE'] ? Region::getCnName($value['PROVINCE']) : ''; $cityName = $value['CITY'] ? Region::getCnName($value['CITY']) : ''; $countyName = $value['COUNTY'] ? Region::getCnName($value['COUNTY']) : ''; $userId = $value['USER_NAME']; $userName = $value['REAL_NAME']; $address = $provinceName . $cityName . $countyName . $value['ADDRESS']; $mobile = $value['MOBILE']; $orderAt = Date::convert($value['CREATED_AT'],'Y-m-d H:i:s'); $orderSn = $value['SN']; // 总价 $totalAmount = $value['BUY_NUMS'] * $value['REAL_PRICE']; $orderAmount += $totalAmount; $orderNums += $value['BUY_NUMS']; // 税额 $taxAmount = Tool::calculateTax($value['REAL_PRICE'], $value['TAX_RATE'], $value['BUY_NUMS']); $totalTaxAmount += $taxAmount; $taxAmount = Tool::formatAmount($taxAmount); $totalAmount = Tool::formatAmount($totalAmount); // 订单详情 $orderDetails .= << {$value['SKU_CODE']} {$value['GOODS_TITLE']} {$value['REAL_PRICE']} {$value['BUY_NUMS']} {$value['TAX_RATE']} {$taxAmount} {$totalAmount} EOT; } $memberCode = Yii::t('app', 'memberCode'); $memberName = Yii::t('app', 'memberName'); $memberAddress = Yii::t('app', 'memberAddress'); $memberPhone = Yii::t('app', 'memberPhone'); $orderCode = Yii::t('app', 'orderCode'); $orderDetail = Yii::t('app', 'orderDetail'); $productCode = Yii::t('app', 'productCode'); $productName = Yii::t('app', 'productName'); $productPrice = Yii::t('app', 'productPrice'); $quantity = Yii::t('app', 'qty'); $taxRate = Yii::t('app', 'taxRate'); $totalTax = Yii::t('app', 'totalTax'); $totalAmount = Yii::t('app', 'totalAmount'); $total = Yii::t('app', 'total'); $signature = Yii::t('app', 'signature'); $date = Yii::t('app', 'date'); $createAt = Yii::t('app', 'createAt'); // 订单基本信息 $orderBase = << {$memberCode} {$userId} {$memberName} {$userName} {$memberAddress} {$address} {$memberPhone} {$mobile} {$orderCode} {$orderSn} {$createAt} {$orderAt} {$orderDetail} ORDER; $l['a_meta_charset'] = 'UTF-8'; $l['a_meta_dir'] = 'ltr'; $l['a_meta_language'] = 'zh'; $l['w_page'] = '页面'; $orderAmount = Tool::formatAmount($orderAmount); $totalTaxAmount = Tool::formatAmount($totalTaxAmount); $context = << {$orderDetail}

{$orderDetail}

{$orderBase} {$orderDetails}
{$productCode} {$productName} {$productPrice} {$quantity} {$taxRate} {$totalTax} {$totalAmount}
{$total} {$orderNums} {$totalTaxAmount} {$orderAmount}
{$signature}:
{$date}:
ORDER; require_once (\Yii::$app->vendorPath . '/tecnickcom/tcpdf/tcpdf.php'); $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); // 设置打印模式 $pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor('DaZe'); $pdf->SetTitle($orderSn); $pdf->SetSubject('TCPDF Tutorial'); $pdf->SetKeywords('TCPDF, PDF, example, test, guide'); // 是否显示页眉 $pdf->setPrintHeader(false); // 设置页眉字体 $pdf->setHeaderFont(Array('dejavusans', '', '12')); // 页眉距离顶部的距离 $pdf->SetHeaderMargin('5'); // 是否显示页脚 $pdf->setPrintFooter(false); // 设置默认等宽字体 $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); // 设置行高 $pdf->setCellHeightRatio(1); // 设置左、上、右的间距 $pdf->SetMargins('15', '15', '15'); // 设置是否自动分页 距离底部多少距离时分页 $pdf->SetAutoPageBreak(TRUE, '15'); // 设置图像比例因子 $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); if (@file_exists(\Yii::$app->vendorPath . 'tecnickcom/tcpdf/examples/lang/eng.php')) { require_once(\Yii::$app->vendorPath . '/tecnickcom/tcpdf/examples/lang/eng.php'); $pdf->setLanguageArray($l); } $pdf->setFontSubsetting(true); $pdf->AddPage(); // 设置字体 $pdf->SetFont('stsongstdlight', '', 10, '', true); // $image_file = \Yii::$app->basePath . '/../frontendEle/src/static/img/ngds-logo.jpg'; // if (!file_exists($image_file)) { // $image_file = \Yii::$app->runtimePath . '/../common/uploads/ngds-logo.jpg'; // } $image_file = \Yii::$app->basePath . '/../ngds-logo.jpg'; $image = file_get_contents($image_file); $pdf->Image('@' . $image, 15, 12, 20, 7, 'JPG'); $pdf->writeHTML($context); $result = $pdf->Output($realFile, 'F'); LoggerTool::debug(['result' => $result]); $this->_updateFirst($realFile, 1); } $this->complete(); return true; } /** * 生成 * @return bool * @throws Exception * @throws InvalidConfigException * @throws \yii\httpclient\Exception */ public function generateDecOrderPDF() { $this->getParams(); if (!$this->params) { throw new Exception('无法获取需要的参数'); } $path = __DS__ . $this->getSaveBasePath() . __DS__ . $this->getSavePath(); $realFile = $path . __DS__ . $this->getFileName('.pdf'); $this->completed = false; $this->getExportId(); $this->getUserId(); $fileNameUpdated = false; // 获取列表数据及表头 $this->_listModel = new $this->listModelClass(); $this->_listModel->isExport = true; // 查询订单数据 // $oderList = $this->_loopWriteDataPDF($realFile, $fileNameUpdated); $orderQuery = Order::find() ->alias('O') ->where($this->params['condition'], $this->params['params']) ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV') ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); // 订单中间表只查询待支付和支付失败的订单 $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value']; // 待支付 $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value']; // 支付失败 $orderStandardQuery = ApproachOrder::find() ->alias('O') ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params']) ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV') ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', ApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); $queryAll = $orderQuery->union($orderStandardQuery, true); $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]); $oderList = $query->all(); if ($oderList) { $userId = ''; $userName = ''; $address = ''; $mobile = ''; $orderAt = ''; $orderDetails = ''; $orderSn = ''; $orderAmount = 0; // 合计总额 $orderNums = 0; // 合计总数 $totalTaxAmount = 0; // 合计税额 $totalAmount = 0; foreach ($oderList as $key => $value) { $provinceName = $value['PROVINCE'] ? Region::getCnName($value['PROVINCE']) : ''; $cityName = $value['CITY'] ? Region::getCnName($value['CITY']) : ''; $countyName = $value['COUNTY'] ? Region::getCnName($value['COUNTY']) : ''; $userId = $value['USER_NAME']; $userName = $value['REAL_NAME']; $address = $provinceName . $cityName . $countyName . $value['ADDRESS']; $mobile = $value['MOBILE']; $orderAt = Date::convert($value['CREATED_AT'],'Y-m-d H:i:s'); $orderSn = $value['SN']; // 总价 $totalAmount = $value['BUY_NUMS'] * $value['REAL_PRICE']; $orderAmount += $totalAmount; $orderNums += $value['BUY_NUMS']; // 税额 $taxAmount = Tool::calculateTax($value['REAL_PRICE'], $value['TAX_RATE'], $value['BUY_NUMS']); $totalTaxAmount += $taxAmount; $taxAmount = Tool::formatAmount($taxAmount); $totalAmount = Tool::formatAmount($totalAmount); // 订单详情 $orderDetails .= << {$value['SKU_CODE']} {$value['GOODS_TITLE']} {$value['REAL_PRICE']} {$value['BUY_NUMS']} {$value['TAX_RATE']} {$taxAmount} {$totalAmount} EOT; } $memberCode = Yii::t('app', 'memberCode'); $memberName = Yii::t('app', 'memberName'); $memberAddress = Yii::t('app', 'memberAddress'); $memberPhone = Yii::t('app', 'memberPhone'); $orderCode = Yii::t('app', 'orderCode'); $orderDetail = Yii::t('app', 'orderDetail'); $productCode = Yii::t('app', 'productCode'); $productName = Yii::t('app', 'productName'); $productPrice = Yii::t('app', 'productPrice'); $quantity = Yii::t('app', 'qty'); $taxRate = Yii::t('app', 'taxRate'); $totalTax = Yii::t('app', 'totalTax'); $totalAmount = Yii::t('app', 'totalAmount'); $total = Yii::t('app', 'total'); $signature = Yii::t('app', 'signature'); $date = Yii::t('app', 'date'); $createAt = Yii::t('app', 'createAt'); // 订单基本信息 $orderBase = << {$memberCode} {$userId} {$memberName} {$userName} {$memberAddress} {$address} {$memberPhone} {$mobile} {$orderCode} {$orderSn} {$createAt} {$orderAt} {$orderDetail} ORDER; $l['a_meta_charset'] = 'UTF-8'; $l['a_meta_dir'] = 'ltr'; $l['a_meta_language'] = 'zh'; $l['w_page'] = '页面'; $orderAmount = sprintf('%.2f', $orderAmount); $totalTaxAmount = sprintf('%.2f', $totalTaxAmount); $context = << {$orderDetail}

{$orderDetail}

{$orderBase} {$orderDetails}
{$productCode} {$productName} {$productPrice} {$quantity} {$taxRate} {$totalTax} {$totalAmount}
{$total} {$orderNums} {$totalTaxAmount} {$orderAmount}
{$signature}:
{$date}:
ORDER; require_once (\Yii::$app->vendorPath . '/tecnickcom/tcpdf/tcpdf.php'); $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); // 设置打印模式 $pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor('DaZe'); $pdf->SetTitle($orderSn); $pdf->SetSubject('TCPDF Tutorial'); $pdf->SetKeywords('TCPDF, PDF, example, test, guide'); // 是否显示页眉 $pdf->setPrintHeader(false); // 设置页眉字体 $pdf->setHeaderFont(Array('dejavusans', '', '12')); // 页眉距离顶部的距离 $pdf->SetHeaderMargin('5'); // 是否显示页脚 $pdf->setPrintFooter(false); // 设置默认等宽字体 $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); // 设置行高 $pdf->setCellHeightRatio(1); // 设置左、上、右的间距 $pdf->SetMargins('10', '10', '10'); // 设置是否自动分页 距离底部多少距离时分页 $pdf->SetAutoPageBreak(TRUE, '15'); // 设置图像比例因子 $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); if (@file_exists(\Yii::$app->vendorPath . 'tecnickcom/tcpdf/examples/lang/eng.php')) { require_once(\Yii::$app->vendorPath . '/tecnickcom/tcpdf/examples/lang/eng.php'); $pdf->setLanguageArray($l); } $pdf->setFontSubsetting(true); $pdf->AddPage(); // 设置字体 $pdf->SetFont('stsongstdlight', '', 10, '', true); $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); // $image_file = \Yii::$app->basePath . '/../frontendEle/src/static/img/ngds-logo.jpg'; // if (!file_exists($image_file)) { // $image_file = \Yii::$app->runtimePath . '/../common/uploads/ngds-logo.jpg'; // } $image_file = \Yii::$app->basePath . '/../ngds-logo.jpg'; $image = file_get_contents($image_file); $pdf->Image('@' . $image, 165, 5, 20, 10, 'JPG'); $pdf->writeHTML($context); $pdf->Output($realFile, 'F'); $this->_updateFirst($realFile, 1); } $this->complete(); return true; } /** * 循环写入数据 * @param $realFile * @param $fileNameUpdated * @param int $page * @param int $counter * @return array * @throws Exception */ private function _loopWriteDataPDF($realFile, &$fileNameUpdated, $page = 0, $counter = 0){ if(method_exists($this->_listModel, 'getList')){ $list = $this->_listModel->getList(['condition'=>$this->params['condition'], 'params'=>isset($this->params['params']) ? $this->params['params'] : [], 'others'=>isset($this->params['others']) ? $this->params['others'] : [], 'page'=>$page, 'pageSize'=>$this->pageSize, 'userId'=>$this->userId]); } else { throw new Exception($this->listModelClass.'的getList方法不存在'); } return $list['list']; } /** * 生成 * @return bool * @throws Exception * @throws InvalidConfigException * @throws \yii\httpclient\Exception */ public function generateBaOrderExcel() { $this->getParams(); if (!$this->params) { throw new Exception('无法获取需要的参数'); } $path = $this->getSaveBasePath() . __DS__ . $this->getSavePath(); $path = __DS__ . $path; $realFile = $this->mkdir($path) . __DS__ . $this->getFileName(); $this->completed = false; $this->getExportId(); $this->getUserId(); $this->_fp = fopen($realFile, 'w'); @exec('chown -R www:www /'.$realFile); @exec('chmod -R 777 /'.$realFile); // 获取列表数据及表头 $this->_listModel = new $this->listModelClass(); $this->_listModel->isExport = true; if(method_exists($this->_listModel, 'getExportHeaders')){ if(method_exists($this->_listModel, 'exportPrepare')) {//导出数据提前设置参数 $this->_listModel->exportPrepare(['condition' => $this->params['condition'], 'params' => $this->params['params'], 'others' => $this->params['others'] ?? [], 'page' => 0, 'pageSize' => 100000, 'userId' => $this->userId]); } $headers = $this->_listModel->getExportHeaders($this->userId); fputcsv($this->_fp, $headers); unset($headers); $this->_updateFirst($realFile, 1); } else { throw new Exception($this->listModelClass.'的getExportHeaders方法不存在'); } $this->_loopWriteDataBaOrder(); $this->complete(); return true; } /** * 循环写入数据 */ private function _loopWriteDataBaOrder() { $orderQuery = BaOrder::find() ->alias('O') ->where($this->params['condition'], $this->params['params']) ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV') ->join('LEFT JOIN', BaUser::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', BaOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); // 订单中间表只查询待支付和支付失败的订单 $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value']; // 待支付 $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value']; // 支付失败 $orderStandardQuery = BaApproachOrder::find() ->alias('O') ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params']) ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV') ->join('LEFT JOIN', BaUser::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', BaApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); $queryAll = $orderQuery->union($orderStandardQuery, true); $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]); $lists = $query->all(); if(!empty($lists)){ $regionConfig = Cache::getRegionConfig(); foreach($lists as $columnData) { $CREATE_USER_ID = Info::getBaUserIdByUserName($columnData['CREATE_USER']); $createUserName = Info::getBaUserRealNameByUserId($CREATE_USER_ID); $decUserName = Info::getBaUserNameByUserId($columnData['DEC_ID']); $columnAccept = [ 'USER_NAME' => $columnData['USER_NAME'], 'DEC_USER_NAME' => $decUserName, 'CREATE_USER' => $columnData['CREATE_USER'], 'CREATE_USER_NAME' => $createUserName, 'SN' => $columnData['SN'], 'STATUS' => Tool::paramConvert(\Yii::$app->params['orderStatus'])[$columnData['STATUS']]['label'] ?? '', 'SKU_CODE' => $columnData['SKU_CODE'], 'GOODS_TITLE' => $columnData['GOODS_TITLE'], 'BUY_NUMS' => $columnData['BUY_NUMS'], 'CONSIGNEE' => $columnData['CONSIGNEE'], 'MOBILE' => "\t{$columnData['MOBILE']}", 'TEL' => "\t{$columnData['TEL']}", 'PROVINCE' => $regionConfig[$columnData['PROVINCE']]['REGION_NAME'] ?? '', 'CITY' => $regionConfig[$columnData['CITY']]['REGION_NAME'] ?? '', 'COUNTY' => $regionConfig[$columnData['COUNTY']]['REGION_NAME'] ?? '', 'ADDRESS' => $columnData['ADDRESS'], 'PERIOD_NUM' => $columnData['PERIOD_NUM'], 'ORDER_TYPE' => ($columnData['ORDER_TYPE'] == 'ZC') ? 'Welcome pack' : (in_array($columnData['PAY_TYPE'], ['cash', 'pay_stack']) ? 'Reselling': 'Points'), 'CREATED_AT' => Date('Y-m-d H:i:s', $columnData['CREATED_AT']), 'PAY_TYPE' => ShopGoods::payTypes()[$columnData['PAY_TYPE']]['name'] ?? ShopGoods::payTypes()['cash']['name'], 'PAY_AT' => $columnData['PAY_AT'] > 0 ? Date('Y-m-d H:i:s', $columnData['PAY_AT']) : '', 'DELIVERY_AT' => $columnData['DELIVERY_AT'] > 0 ? Date('Y-m-d H:i:s', $columnData['DELIVERY_AT']) : '', 'REAL_PRICE' => $columnData['REAL_PRICE'] ?? 0, 'REAL_PV' => $columnData['REAL_PV'] ?? 0, 'PAY_FREIGHT' => $columnData['PAY_FREIGHT'] ?? 0, 'TAX_RATE' => $columnData['TAX_RATE'], 'TAX_AMOUNT' => Tool::calculateTax($columnData['REAL_PRICE'], $columnData['TAX_RATE'], $columnData['BUY_NUMS']), 'EXPRESS_COMPANY' => $columnData['EXPRESS_COMPANY'], 'ORDER_TRACK_NO' => $columnData['ORDER_TRACK_NO'], 'EXPRESS_TYPE' => $columnData['EXPRESS_TYPE'] == 0 ? 'mailing ':' auto pick', 'FRONT_REMARK' => $columnData['FRONT_REMARK'], 'DELIVERY_STATUS_NAME' => Tool::paramConvert(\Yii::$app->params['deliveryStatus'])[$columnData['DELIVERY_STATUS']]['label'] ?? '', ]; fputcsv($this->_fp, Tool::arrTextConvert($columnAccept)); unset($percent, $columnData, $columnAccept); } unset($list); } unset($list); return 'finish'; } /** * 生成 * @return bool * @throws Exception * @throws InvalidConfigException * @throws \yii\httpclient\Exception */ public function generateBaOrderPDF() { $this->getParams(); if (!$this->params) { throw new Exception('无法获取需要的参数'); } $path = __DS__ . $this->getSaveBasePath() . __DS__ . $this->getSavePath(); $realFile = $path . __DS__ . $this->getFileName('.pdf'); $this->completed = false; $this->getExportId(); $this->getUserId(); $fileNameUpdated = false; // 获取列表数据及表头 $this->_listModel = new $this->listModelClass(); $this->_listModel->isExport = true; // 查询订单数据 $orderQuery = BaOrder::find() ->alias('O') ->where($this->params['condition'], $this->params['params']) ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV') ->join('LEFT JOIN', BaUser::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', BaOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); // 订单中间表只查询待支付和支付失败的订单 $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value']; // 待支付 $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value']; // 支付失败 $orderStandardQuery = BaApproachOrder::find() ->alias('O') ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params']) ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV') ->join('LEFT JOIN', BaUser::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', BaApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->orderBy('O.CREATED_AT DESC'); $queryAll = $orderQuery->union($orderStandardQuery, true); $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]); $oderList = $query->all(); if ($oderList) { $userId = ''; $userName = ''; $address = ''; $mobile = ''; $orderAt = ''; $orderDetails = ''; $orderSn = ''; $orderAmount = 0; // 合计总额 $orderNums = 0; // 合计总数 $totalTaxAmount = 0; // 合计税额 $totalAmount = 0; foreach ($oderList as $key => $value) { $provinceName = $value['PROVINCE'] ? Region::getCnName($value['PROVINCE']) : ''; $cityName = $value['CITY'] ? Region::getCnName($value['CITY']) : ''; $countyName = $value['COUNTY'] ? Region::getCnName($value['COUNTY']) : ''; $userId = $value['USER_NAME']; $userName = $value['REAL_NAME']; $address = $provinceName . $cityName . $countyName . $value['ADDRESS']; $mobile = $value['MOBILE']; $orderAt = Date::convert($value['CREATED_AT'],'Y-m-d H:i:s'); $orderSn = $value['SN']; // 总价 $totalAmount = $value['BUY_NUMS'] * $value['REAL_PRICE']; $orderAmount += $totalAmount; $orderNums += $value['BUY_NUMS']; // 税额 $taxAmount = Tool::calculateTax($value['REAL_PRICE'], $value['TAX_RATE'], $value['BUY_NUMS']); $totalTaxAmount += $taxAmount; $taxAmount = Tool::formatAmount($taxAmount); $totalAmount = Tool::formatAmount($totalAmount); // 订单详情 $orderDetails .= << {$value['SKU_CODE']} {$value['GOODS_TITLE']} {$value['REAL_PRICE']} {$value['BUY_NUMS']} {$value['TAX_RATE']} {$taxAmount} {$totalAmount} EOT; } // 订单基本信息 $orderBase = << Member Code {$userId} Member Name {$userName} Member Address {$address} Member Phone {$mobile} Order Code {$orderSn} Creation Time {$orderAt} Order Detail ORDER; $l['a_meta_charset'] = 'UTF-8'; $l['a_meta_dir'] = 'ltr'; $l['a_meta_language'] = 'zh'; $l['w_page'] = '页面'; $orderAmount = Tool::formatAmount($orderAmount); $totalTaxAmount = Tool::formatAmount($totalTaxAmount); $context = << Order detail

Order detail

{$orderBase} {$orderDetails}
Product Code Product Name Product Price Qty Tax Rate Tax Total Amount
Total {$orderNums} {$totalTaxAmount} {$orderAmount}
Signature:
Date:
ORDER; require_once (\Yii::$app->vendorPath . '/tecnickcom/tcpdf/tcpdf.php'); $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); // 设置打印模式 $pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor('DaZe'); $pdf->SetTitle($orderSn); $pdf->SetSubject('TCPDF Tutorial'); $pdf->SetKeywords('TCPDF, PDF, example, test, guide'); // 是否显示页眉 $pdf->setPrintHeader(false); // 设置页眉字体 $pdf->setHeaderFont(Array('dejavusans', '', '12')); // 页眉距离顶部的距离 $pdf->SetHeaderMargin('5'); // 是否显示页脚 $pdf->setPrintFooter(false); // 设置默认等宽字体 $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); // 设置行高 $pdf->setCellHeightRatio(1); // 设置左、上、右的间距 $pdf->SetMargins('10', '0', '10'); // 设置是否自动分页 距离底部多少距离时分页 $pdf->SetAutoPageBreak(TRUE, '15'); // 设置图像比例因子 $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); if (@file_exists(\Yii::$app->vendorPath . 'tecnickcom/tcpdf/examples/lang/eng.php')) { require_once(\Yii::$app->vendorPath . '/tecnickcom/tcpdf/examples/lang/eng.php'); $pdf->setLanguageArray($l); } $pdf->setFontSubsetting(true); $pdf->AddPage(); // 设置字体 $pdf->SetFont('stsongstdlight', '', 10, '', true); // $image_file = \Yii::$app->basePath . '/../frontendEle/src/static/img/ngds-logo.jpg'; // if (!file_exists($image_file)) { // $image_file = \Yii::$app->runtimePath . '/../common/uploads/ngds-logo.jpg'; // } $image_file = \Yii::$app->basePath . '/../ngds-logo.jpg'; $image = file_get_contents($image_file); $pdf->Image('@' . $image, 15, 12, 20, 7, 'JPG'); $pdf->writeHTML($context); $pdf->Output($realFile, 'F'); $this->_updateFirst($realFile, 1); } $this->complete(); return true; } /** * 生成 * @return bool * @throws Exception * @throws InvalidConfigException * @throws \yii\httpclient\Exception */ public function actionOrderInvoiceExport() { $this->getParams(); if (!$this->params) { throw new Exception('无法获取需要的参数'); } $path = __DS__ . $this->getSaveBasePath() . __DS__ . $this->getSavePath(); $realFile = $this->mkdir($path) . __DS__ . $this->getFileName('.pdf'); $this->completed = false; $this->getExportId(); $this->getUserId(); $fileNameUpdated = false; // 获取列表数据及表头 $this->_listModel = new $this->listModelClass(); $this->_listModel->isExport = true; // 查询订单数据 // 使用新的查询对象,禁用查询缓存,确保获取最新数据 $query = OrderGoods::find() ->alias('OG') ->where($this->params['condition'], $this->params['params']) ->select('OG.ID AS AID,O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV') ->join('LEFT JOIN', ORDER::tableName() . ' AS O', 'OG.ORDER_SN=O.SN') ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID') ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID') ->asArray() ->noCache(); // 禁用查询缓存 // 添加详细的调试信息 $rawSql = $query->createCommand()->getRawSql(); $oderList = $query->all(); $sn = $oderList[0]['SN']; // 同时使用原生SQL查询进行对比测试 $nativeConnection = Yii::$app->db; $nativeQuery = " SELECT `OG`.`ID` AS `AID`, `O`.*, `U`.`REAL_NAME`, `U`.`DEC_ID`, `SG`.`CATEGORY_TYPE`, `OG`.`REAL_PRICE`, `OG`.`TAX_RATE`, `OG`.`BUY_NUMS`, `OG`.`SKU_CODE`, `OG`.`GOODS_TITLE`, `OG`.`REAL_PV` FROM `AR_ORDER_GOODS` `OG` LEFT JOIN `AR_ORDER` `O` ON OG.ORDER_SN = O.SN LEFT JOIN `AR_USER` `U` ON U.ID = O.USER_ID LEFT JOIN `AR_SHOP_GOODS` `SG` ON SG.ID = OG.GOODS_ID WHERE O.IS_DELETE = 0 AND O.SN = '{$sn}' ORDER BY `O`.`CREATED_AT` DESC"; $nativeResults = $nativeConnection->createCommand($nativeQuery)->queryAll(); // 如果原生查询有结果但Yii查询没有,使用原生查询结果 if(count($nativeResults) > 0 && count($oderList) < count($nativeResults)) { $oderList = $nativeResults; } if ($oderList) { $userId = ''; $userName = ''; $address = ''; $mobile = $oderList[0]['MOBILE']; $orderAt = Date::convert($oderList[0]['CREATED_AT'],'Y/m/d'); $orderDetails = ''; $orderSn = $oderList[0]['SN'];; $orderAmount = 0; // 合计总额 $orderNums = 0; // 合计总数 $totalTaxAmount = 0; // 合计税额 $totalAmount = 0; $paymentStatus = 'Paid'; // 支付状态 $invoiceRemark = $oderList[0]['INVOICE_REMARK']; $paymentMethod = $oderList[0]['PAY_TYPE']; // 支付方式 $currency = Currency::findOne($oderList[0]['CURRENCY_ID'])['CODE'] ?? '';; $invoiceNo = $oderList[0]['INVOICE_NO']; $provinceName = $oderList[0]['PROVINCE'] ? Region::getCnName($oderList[0]['PROVINCE']) : ''; $cityName = $oderList[0]['CITY'] ? Region::getCnName($oderList[0]['CITY']) : ''; $countyName = $oderList[0]['COUNTY'] ? Region::getCnName($oderList[0]['COUNTY']) : ''; $address = $provinceName . $cityName . $countyName . $oderList[0]['ADDRESS']; $paymentMethod = $oderList[0]['PAY_TYPE'] ?? 'Cash'; $paymentStatus = \Yii::$app->params['orderStatus'][$oderList[0]['STATUS']]['label'] ?? 'Paid'; $orderTotalBv = 0; $orderTotalTaxAmount = 0; $orderTotalAmount = 0; $orderTotal = 0; $orderTotalQuantity = count($oderList); $no = 0; foreach ($oderList as $key => $value) { $no += 1; $userId = $value['USER_NAME']; $userName = $value['REAL_NAME']; // 总价 $totalAmount = $value['BUY_NUMS'] * $value['REAL_PRICE']; $orderAmount += $totalAmount; $orderNums += $value['BUY_NUMS']; // 税额 $taxAmount = Tool::calculateTax($value['REAL_PRICE'], $value['TAX_RATE'], $value['BUY_NUMS']); $totalTaxAmount += $taxAmount; $totalBv = $value['BUY_NUMS'] * $value['REAL_PV']; $orderTotalBv += $totalBv; $orderTotalTaxAmount += $taxAmount; $orderTotalAmount += $totalAmount - $taxAmount; $orderTotal += $totalAmount; $totalBvFormat = Tool::formatAmount($totalBv); $taxableAmountFormat =Tool::formatAmount($taxAmount); $vatAmountFormat = Tool::formatAmount($totalAmount - $taxAmount); $totalFormat = Tool::formatAmount($totalAmount); $vatRateFormat = Tool::formatAmount($value['TAX_RATE']) . '%'; $unitPriceFormat = Tool::formatAmount($value['REAL_PRICE']); $unitBvFormat = Tool::formatAmount($value['REAL_PV']); // 订单详情 $orderDetails .= << {$no} {$value['SKU_CODE']} {$value['GOODS_TITLE']} {$value['BUY_NUMS']} {$unitPriceFormat} {$unitBvFormat} {$totalBvFormat} {$taxableAmountFormat} {$vatRateFormat} {$vatAmountFormat} {$totalFormat} EOT; } $memberCode = Yii::t('app', 'memberCode'); $memberName = Yii::t('app', 'memberName'); $memberAddress = Yii::t('app', 'memberAddress'); $memberPhone = Yii::t('app', 'memberPhone'); $orderCode = Yii::t('app', 'orderCode'); $taxInvoice = Yii::t('app', 'taxInvoice'); $productCode = Yii::t('app', 'productCode'); $productName = Yii::t('app', 'productName'); $productPrice = Yii::t('app', 'productPrice'); $quantity = Yii::t('app', 'qty'); $taxRate = Yii::t('app', 'taxRate'); $totalTax = Yii::t('app', 'totalTax'); $totalAmount = Yii::t('app', 'totalAmount'); $total = Yii::t('app', 'total'); $signature = Yii::t('app', 'signature'); $date = Yii::t('app', 'date'); $createAt = Yii::t('app', 'createAt'); $l['a_meta_charset'] = 'UTF-8'; $l['a_meta_dir'] = 'ltr'; $l['a_meta_language'] = 'zh'; $l['w_page'] = '页面'; $orderAmount = Tool::formatAmount($orderAmount); $totalTaxAmount = Tool::formatAmount($totalTaxAmount); $orderTotalBv = Tool::formatAmount($orderTotalBv); $orderTotalTaxAmount = Tool::formatAmount($orderTotalTaxAmount); $orderTotalAmount = Tool::formatAmount($orderTotalAmount); $orderTotal = Tool::formatAmount($orderTotal); $context = << {$taxInvoice}

Tax Invoice

Elken Arabiya General Grading Co.LLC

Shop No.2, Plot 356-1142, Juneirah Street, Umm Suqeim 1, Dubai, UAE

Phone: +971042296118

License No: 1314319

VAT No: {$orderSn}




Bill to Invoice No.: {$invoiceNo}
Name of Distributor: {$userName} Date: {$orderAt}
Member ID: {$userId} Payment status: {$paymentStatus}
Address: {$address}
Contact: {$mobile}



{$orderDetails}
No. Product Code Product Name Quantity Unit Price({$currency}) Unit BV Total BV Taxable Amount({$currency}) VAT Rate VAT Amount({$currency}) Total({$currency})
Grand Total {$orderTotalQuantity} {$orderTotalBv} {$orderTotalTaxAmount} {$orderTotalAmount} {$orderTotal}
Total Amount {$currency}{$orderAmount}
Method:
Paid amount: {$currency}{$orderAmount}
Remark:
{$invoiceRemark}
Issued By: Picked By: Received By:
ORDER; require_once (\Yii::$app->vendorPath . '/tecnickcom/tcpdf/tcpdf.php'); $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); // 设置打印模式 $pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor('DaZe'); $pdf->SetTitle($orderSn); $pdf->SetSubject('TCPDF Tutorial'); $pdf->SetKeywords('TCPDF, PDF, example, test, guide'); // 是否显示页眉 $pdf->setPrintHeader(false); // 设置页眉字体 $pdf->setHeaderFont(Array('Helvetica', '', '12')); // 页眉距离顶部的距离 $pdf->SetHeaderMargin('5'); // 是否显示页脚 $pdf->setPrintFooter(false); // 设置默认等宽字体 $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); // 设置行高 // $pdf->setCellHeightRatio(1); // 设置左、上、右的间距 $pdf->SetMargins('10', '0', '10'); // 设置是否自动分页 距离底部多少距离时分页 $pdf->SetAutoPageBreak(TRUE, '15'); // 设置图像比例因子 $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); if (@file_exists(\Yii::$app->vendorPath . 'tecnickcom/tcpdf/examples/lang/eng.php')) { require_once(\Yii::$app->vendorPath . '/tecnickcom/tcpdf/examples/lang/eng.php'); $pdf->setLanguageArray($l); } $pdf->setFontSubsetting(true); $pdf->AddPage(); // 设置字体 $pdf->SetFont('Helvetica', '', 10, '', true); // $image_file = \Yii::$app->basePath . '/../ngds-logo.jpg'; // $image = file_get_contents($image_file); // $pdf->Image('@' . $image, 15, 12, 20, 7, 'JPG'); $pdf->writeHTML($context); $result = $pdf->Output($realFile, 'F'); $this->_updateFirst($realFile, 1); } $this->complete(); return true; } }