当前位置: 首页 > news >正文

PHP全电发票OFD生成实战

基于PHP的全电发票OFD文件生成案例

OFD(Open Fixed-layout Document)是一种国产的版式文档格式,广泛应用于电子发票、电子证照等领域。全电发票作为税务数字化的重要环节,其OFD文件的生成需要遵循严格的技术规范。以下通过PHP实现OFD文件生成的完整案例。

环境准备

PHP 7.4或更高版本
需要安装zip扩展(OFD本质是ZIP压缩包)
推荐使用Composer安装依赖包:

composer require smalot/pdfparser   // 用于解析PDF模板(如需)
composer require endroid/qr-code    // 生成二维码
OFD文件结构分析

标准OFD文件包含以下目录结构:

OFD/
├── Doc_0/
│   ├── Pages/
│   ├── PublicRes.xml
│   ├── Document.xml
│   ├── Res/
└── OFD.xml
核心代码实现

1. 创建基础文件结构

function createOFDStructure(string $outputPath): void {$baseDir = $outputPath . '/OFD';mkdir($baseDir, 0777, true);$subDirs = ['Doc_0/Pages','Doc_0/Res'];foreach ($subDirs as $dir) {mkdir($baseDir . '/' . $dir, 0777, true);}// 创建占位文件file_put_contents($baseDir . '/OFD.xml', generateOFDRoot());file_put_contents($baseDir . '/Doc_0/Document.xml', generateDocumentRoot());
}

2. 生成OFD.xml(根文件)

function generateOFDRoot(): string {return <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<OFD xmlns="http://www.ofdspec.org/2016" Version="1.0"><DocBody><DocInfo><DocID>OFD_</DocID><Title>电子发票</Title></DocInfo><DocRoot>Doc_0/Document.xml</DocRoot></DocBody>
</OFD>
XML;
}

3. 发票内容填充模板

function generateInvoiceContent(array $data): string {$qrContent = sprintf("发票代码:%s\n发票号码:%s\n金额:¥%.2f",$data['code'],$data['number'],$data['amount']);$qrCode = (new QrCode($qrContent))->setSize(200)->setMargin(10)->writeString();$html = <<<HTML
<div style="position: absolute; left: 100mm; top: 50mm;"><h1>电子发票</h1><p>发票代码:{$data['code']}</p><p>发票号码:{$data['number']}</p><img src="data:image/png;base64," . base64_encode($qrCode) . ">
</div>
HTML;return convertHtmlToOFD($html); // 需要实现HTML到OFD坐标的转换
}

4. PDF转OFD核心转换

function pdfToOFD(string $pdfPath, string $outputDir): void {$parser = new \Smalot\PdfParser\Parser();$pdf = $parser->parseFile($pdfPath);$pages = $pdf->getPages();foreach ($pages as $index => $page) {$content = $page->getText();$ofdPage = generateOFDPage($content, $index);file_put_contents("{$outputDir}/Doc_0/Pages/Page_{$index}.xml",$ofdPage);}updateDocumentXML(count($pages), $outputDir);
}

5. 生成Page_N.xml文件

function generateOFDPage(string $content, int $pageIndex): string {$layerId = "Layer_{$pageIndex}";return <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<Page xmlns="http://www.ofdspec.org/2016" ID="{$pageIndex}" BaseLoc="Res/PageRes.xml" PhysicalBox="0 0 210 297"><Content><Layer ID="{$layerId}"><TextObject ID="1" Boundary="10 10 190 277"><TextCode X="15" Y="20">{$content}</TextCode></TextObject></Layer></Content>
</Page>
XML;
}
关键问题解决方案

1. 坐标系统转换

OFD采用毫米为单位的绝对坐标:

function mmToPoint(float $mm): float {return $mm * 2.83465; // 1mm ≈ 2.83465点
}

2. 二维码生成优化

使用Endroid QR Code库时添加发票专用容错:

$qrCode = (new QrCode($content))->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH)->setEncoding('UTF-8')->setRoundBlockSizeMode(RoundBlockSizeMode::MARGIN);

3. 批量生成处理

对于大批量发票生成,建议采用队列处理:

// 使用Redis队列
$redis = new Redis();
$redis->connect('127.0.0.1');
while ($data = $redis->rpop('invoice_queue')) {generateOFDInvoice(json_decode($data, true));
}
完整调用示例
$invoiceData = ['code' => '144021900111','number' => '12345678','amount' => 486.50,'seller' => '某某科技有限公司','buyer' => '测试客户'
];$outputPath = '/var/www/invoices/OFD_'.time();
createOFDStructure($outputPath);
generateInvoiceContent($invoiceData, $outputPath);// 压缩为最终OFD文件
$zip = new ZipArchive();
$zip->open($outputPath.'.ofd', ZipArchive::CREATE);
addFolderToZip($outputPath.'/OFD', $zip);
$zip->close();
注意事项
  1. 必须遵循《GB/T 33190-2016》OFD国家标准
  2. 电子发票需要包含税务监制章数字签名
  3. 实际生产环境应添加异常处理:
try {generateOFDInvoice($data);
} catch (OFDException $e) {logError($e->getMessage());retryLater($data);
}

通过上述实现方案,可以构建符合税务要求的全电发票OFD生成系统。实际应用中还需结合数字签名、发票流水号管理等完整业务流程。

http://www.dtcms.com/a/516209.html

相关文章:

  • 利用DuckDB SQL求解集合数学题
  • 做新闻h5网站专业网站建设费用报价
  • 个人网站开发的环境海南省建设网站的公司电话号码
  • C++学习:C++11关于类型的处理
  • LayoutManager
  • 网站建设公司盈利分析网站建设需要哪些的ps
  • QML学习笔记(四十六)QML与C++交互:Q_PROPERTY宏映射
  • 培训学校 网站费用购物商城网站建设方案
  • 黑马商城day5-服务保护和分布式事务
  • 【实证分析】地市人才及资本创新要素流动数据集-含代码(2003-2023年)
  • 【学习系列】SAP RAP 16:RAP应用部署集成至Fiori Launchpad 【On-Premise】
  • 01-JavaScript基础
  • 万亿国债助力应急行业-多链路聚合通信路由在应急项目中的解决方案和技术需求
  • CSS3 超实用属性:pointer-events (可穿透图层的鼠标事件)
  • 企业做网站公司有哪些wordpress 积分支付
  • Java线程阻塞状态
  • 网站优化排名软件哪些最好99企业邮箱
  • dify之Web 前端工作流编排(Workflow Builder)
  • 环境变量进阶:本地变量、内建命令与全局属性的深度解析
  • 《图解技术体系》Wonderful talk AI ~~Google AI
  • 咸阳网站建设培训学校国外网站 国内访问速度
  • 建设一个网站的工作方案企业信息公开网查询
  • 半导体晶圆制造关于设备制程几个核心概念及映射关系
  • 欧美购物网站排名国内自动化网站建设
  • DeepSeek-OCR: Contexts Optical Compression 详解
  • 第七章 查找——课后习题解练【数据结构(c语言版 第2版)】
  • 江西建设安全网站公司注册查询核名
  • 常用docker命令速查表
  • 响应式酒店网站模板做公司网站要多久
  • 1号店网站网页特效企业网站建设方案价位