You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua无外部模块生成PDF仅显示首行问题求助

Lua生成PDF仅显示表格第一行的解决方案

问题根源

你的代码里for循环缺少闭合的end语句,导致content_stream = content_stream .. "ET\n"以及后续写文件的逻辑都被包含在第一次循环迭代里。循环只执行一次就跳出,自然只会生成第一行内容。

修复步骤

  1. 给for循环补上end,让所有表格元素都能被遍历处理
  2. 修正PDF交叉引用(xref)的字节偏移量——原代码硬编码的偏移值会因为内容长度变化失效,改成动态计算每个对象的位置更可靠

修正后的完整代码

local patch = {
    {FID = 17, IDType = "nothing", CID = "nothing", Name = "Mac Aura PXL 1", Mode = "Standard", Uaddrs = 1.301},
    {FID = 18, IDType = "something", CID = "controller", Name = "Spot Moving Head", Mode = "Advanced", Uaddrs = 2.101},
    {FID = 19, IDType = "example", CID = "another", Name = "Wash Light", Mode = "Standard", Uaddrs = 3.401}
}

local function escape_pdf_string(str)
    return str:gsub("\\", "\\\\"):gsub("%(", "\\("):gsub("%)", "\\)")
end

local file = io.open("patch_corrected.pdf", "wb")

-- 记录每个PDF对象的字节偏移
local offsets = {}
offsets[0] = file:seek()
file:write("%PDF-1.4\n")

offsets[1] = file:seek()
file:write("1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n")

offsets[2] = file:seek()
file:write("2 0 obj\n<< /Type /Pages /Count 1 /Kids [3 0 R] >>\nendobj\n")

offsets[3] = file:seek()
file:write("3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >>\nendobj\n")

-- 生成内容流
local content_stream = "BT\n/F1 12 Tf\n"
local y_position = 800 

for index, element in ipairs(patch) do
    local line = string.format("FID: %d, IDType: %s, CID: %s, Name: %s, Mode: %s, Uaddrs: %.3f",
        element.FID, element.IDType, element.CID, element.Name, element.Mode, element.Uaddrs)
    line = escape_pdf_string(line) 
    content_stream = content_stream .. string.format("50 %d Td\n(%s) Tj\n", y_position, line)
    y_position = y_position - 40 
end -- 补上缺失的end

content_stream = content_stream .. "ET\n"

-- 写入内容对象
offsets[4] = file:seek()
file:write(string.format("4 0 obj\n<< /Length %d >>\nstream\n%s\nendstream\nendobj\n", #content_stream, content_stream))

-- 写入字体对象
offsets[5] = file:seek()
file:write("5 0 obj\n<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>\nendobj\n")

-- 写入交叉引用表
local xref_start = file:seek()
file:write("xref\n")
file:write("0 6\n")
file:write(string.format("%010d 65535 f \n", offsets[0]))
for i=1,5 do
    file:write(string.format("%010d 00000 n \n", offsets[i]))
end

-- 写入trailer和EOF
file:write("trailer\n")
file:write("<< /Root 1 0 R /Size 6 >>\n")
file:write("startxref\n")
file:write(xref_start .. "\n")
file:write("%%EOF\n")

file:close()

print("修正后的PDF已生成:patch_corrected.pdf")

额外提示

手动生成PDF时,交叉引用的字节偏移是很容易出错的点——硬编码的数值只要内容长度有变化就会失效,动态计算每个对象的位置能避免这类问题。另外要严格遵循PDF语法规范,任何语法错误都可能导致阅读器无法正确渲染内容。

内容的提问来源于stack exchange,提问作者Josh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 17:52:31