Files
ofdgo/README.md
T
2026-10-19 09:29:36 +08:00

323 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OFDGo [![PkgGoDev](https://pkg.go.dev/badge/github.com/xiaoqidun/ofdgo)](https://pkg.go.dev/github.com/xiaoqidun/ofdgo)
首个原生、全平台、纯 Go 语言高性能 OFD 引擎
# 主要能力
- 文档处理:创建、读写、拆分、合并、压缩
- 渲染转换:矢量、位图、导入、导出、批量
- 文档安全:签名、签章、验签、加密、解密
- 电子发票:提取、创建、编辑、校验、同步
- 页面管理:添加、导入、复制、排序、删除
- 文字处理:插入、编辑、排版、搜索、提取
- 文字样式:选区、混排、装饰、阴影、底色
- 字体处理:匹配、内嵌、外置、子集、提取
- 图片处理:插入、替换、缩放、裁剪、提取
- 图形处理:绘制、变换、组合、对齐、分布
- 色彩管理:空间、配置、转换、渐变、透明
- 文档管理:添加、切换、改名、排序、删除
- 版本管理:创建、切换、改名、另存、删除
- 文档结构:目录、书签、模板、标引、扩展
- 资源管理:字体、图片、色彩、媒体、附件
- 注解管理:批注、高亮、水印、印章、链接
- 动作管理:跳转、链接、附件、音频、视频
- 三维处理:解析、材质、纹理、动画、渲染
# 在线使用
[OFDGo WebUI](https://ofdgo.aite.me/),将OFDGo编译为WASM提供服务
# 链接接入
```text
https://ofdgo.aite.me/#url=<URL编码后的文件地址>
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `url` | 是 | 文件地址,支持OFD、PDF |
| `name` | 否 | 文件名称,默认自动获取 |
| `page` | 否 | 物理页码,默认1,超过总页数取末页 |
参数用`&`连接,参数值需URL编码。跨域访问时,服务器头需包含:
```http
Access-Control-Allow-Origin: https://ofdgo.aite.me
```
公开资源可设为`*`;自建编辑器替换为对应源(协议、域名及端口)。
# 一键部署
```shell
docker run -d -p 80:80 ccr.ccs.tencentyun.com/xiaoqidun/ofdgo:latest
```
# 构建指南
```batch
:: 1. 编译OFDGo WASM
set GOOS=js
set GOARCH=wasm
go build -o assets/webui/wasm/ofdgo.wasm -trimpath -ldflags "-s -w -buildid=" ./cmd/webui/wasm.go
:: 2. 编译OFDGo WebUI
set GOOS=windows
set GOARCH=amd64
go build -o ofdgo_webui.exe -trimpath -ldflags "-s -w -buildid=" ./cmd/webui/webui.go
```
# 原生桌面
```batch
set GOOS=windows
set GOARCH=amd64
go build -o ofdgo_windows_amd64.exe -trimpath -ldflags "-H windowsgui -s -w -buildid=" ./cmd/webview
```
# 安装引擎
```shell
go get -u github.com/xiaoqidun/ofdgo
```
# 创建文档
```go
package main
import (
"context"
"log"
"os"
"github.com/xiaoqidun/ofdgo"
)
func main() {
// 1. 创建文档
editor := ofdgo.NewEditor()
editor.Info.Title = "示例文档"
page, err := editor.AddPage(210, 297)
if err != nil {
log.Fatal(err)
}
// 2. 添加文字
fontData, err := os.ReadFile("font.ttf")
if err != nil {
log.Fatal(err)
}
fontID, err := editor.AddFont(ofdgo.FontFile{Data: fontData}, 0)
if err != nil {
log.Fatal(err)
}
_, err = editor.AddText(page, ofdgo.Box{X: 20, Y: 20, W: 170, H: 15}, "你好,OFDGo!", fontID, 6)
if err != nil {
log.Fatal(err)
}
// 3. 保存文档
output, err := ofdgo.NewFileOutput("test.ofd")
if err != nil {
log.Fatal(err)
}
if _, err := editor.SaveAs(context.Background(), output, ofdgo.WriteOptions{}); err != nil {
log.Fatal(err)
}
}
```
# 编辑文档
```go
package main
import (
"context"
"log"
"github.com/xiaoqidun/ofdgo"
)
func main() {
// 1. 打开文档
input, err := ofdgo.OpenFile(context.Background(), "test.ofd", ofdgo.InputOptions{})
if err != nil {
log.Fatal(err)
}
defer input.Close()
reader, err := ofdgo.NewReader(input)
if err != nil {
log.Fatal(err)
}
defer reader.Close()
// 2. 编辑标题
editor, err := reader.Editor()
if err != nil {
log.Fatal(err)
}
editor.Info.Title = "编辑后的"
// 3. 另存文档
output, err := ofdgo.NewFileOutput("edited.ofd")
if err != nil {
log.Fatal(err)
}
if _, err := editor.SaveAs(context.Background(), output, ofdgo.WriteOptions{}); err != nil {
log.Fatal(err)
}
}
```
# 转换文档
```go
package main
import (
"context"
"log"
"os"
"github.com/xiaoqidun/ofdgo"
)
func main() {
// 1. 打开文档
input, err := ofdgo.OpenFile(context.Background(), "test.pdf", ofdgo.InputOptions{})
if err != nil {
log.Fatal(err)
}
defer input.Close()
// 2. 创建文件
ofdFile, err := os.Create("test.ofd")
if err != nil {
log.Fatal(err)
}
defer ofdFile.Close()
// 3. 转换文档
report, err := ofdgo.ConvertPDF(context.Background(), input, ofdFile, ofdgo.PDFImportOptions{})
if err != nil {
log.Fatal(err)
}
// 4. 查看警告
for _, warning := range report.Warnings {
log.Printf("第%d页: %s", warning.Page, warning.Message)
}
}
```
# 渲染文档
```go
package main
import (
"context"
"log"
"os"
"github.com/xiaoqidun/ofdgo"
)
func main() {
// 1. 打开OFD文件
input, err := ofdgo.OpenFile(context.Background(), "test.ofd", ofdgo.InputOptions{})
if err != nil {
log.Fatal(err)
}
defer input.Close()
reader, err := ofdgo.NewReader(input)
if err != nil {
log.Fatal(err)
}
defer reader.Close()
// 2. 创建PDF文件
pdfFile, err := os.Create("test.pdf")
if err != nil {
log.Fatal(err)
}
defer pdfFile.Close()
// 3. 渲染PDF文件
renderer := ofdgo.NewRenderer(reader)
if err := renderer.RenderToMultiPagePDF(pdfFile); err != nil {
log.Fatal(err)
}
}
```
# 验证签名
```go
package main
import (
"context"
"log"
"os"
"github.com/xiaoqidun/ofdgo"
)
func main() {
// 1. 打开OFD文件
input, err := ofdgo.OpenFile(context.Background(), "test.ofd", ofdgo.InputOptions{})
if err != nil {
log.Fatal(err)
}
defer input.Close()
// 2. 验证OFD签名
reports, err := ofdgo.VerifySignatures(input)
if err != nil {
log.Fatal(err)
}
// 3. 判断验证结果
if len(reports) == 0 {
log.Println("文件未发现签名")
return
}
valid := true
for _, report := range reports {
if report.IntegrityValid() {
log.Printf("签名%s验证通过", report.ID)
continue
}
valid = false
if report.Error == "" {
log.Printf("签名%s验证失败", report.ID)
} else {
log.Printf("签名%s验证失败: %s", report.ID, report.Error)
}
}
if !valid {
os.Exit(1)
}
}
```
# 提取发票
```go
package main
import (
"context"
"encoding/json"
"log"
"os"
"github.com/xiaoqidun/ofdgo"
)
func main() {
// 1. 打开OFD文件
input, err := ofdgo.OpenFile(context.Background(), "invoice.ofd", ofdgo.InputOptions{})
if err != nil {
log.Fatal(err)
}
defer input.Close()
reader, err := ofdgo.NewReader(input)
if err != nil {
log.Fatal(err)
}
defer reader.Close()
// 2. 提取发票信息
report, err := reader.Invoices()
if err != nil {
log.Fatal(err)
}
// 3. 输出提取结果
encoder := json.NewEncoder(os.Stdout)
encoder.SetIndent("", " ")
if err := encoder.Encode(report); err != nil {
log.Fatal(err)
}
}
```
# 授权协议
本项目使用 [Apache License 2.0](https://github.com/xiaoqidun/ofdgo/blob/main/LICENSE) 授权协议