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

部署内部调用runApp()的Shiny应用(tabulizer包场景)问题咨询

问题解决方案:Shiny线上部署时tabulizer的locate_areas无响应问题

根因说明

locate_areas()是面向本地交互场景设计的函数,运行时会在服务端本地启动一个独立的Shiny小应用。本地调试时用户与服务端为同一设备,可以直接看到弹出的交互界面;部署到线上后,该独立应用仅运行在远端服务器内部,用户浏览器无法接收到对应的交互页面,因此点击后无响应。

可行规避方案

替换locate_areas()的交互逻辑,将选区功能直接集成到你自己的Shiny应用前端,不需要调用额外的内嵌Shiny应用,具体实现逻辑如下:

  1. 用户上传PDF、指定页码后,后端先将目标PDF页渲染为图片传回前端显示
  2. 用Shiny原生的框选交互能力获取用户选中的区域坐标
  3. 坐标单位转换后直接传入extract_tables()函数提取表格

修改后可直接部署的代码

library(shiny)
library(tabulizer)
library(pdftools)
library(png)

ui <- fluidPage(
  fileInput("report", NULL, buttonLabel = "Upload report"),
  numericInput("page", "Specify page number", value = 1, min = 1),
  actionButton("load_page", "Load PDF page"),
  # 用于展示PDF转成的图片并支持框选
  plotOutput("pdf_preview", brush = brushOpts(id = "pdf_brush", resetOnNew = TRUE)),
  actionButton("extract", "Extract table from selected area"),
  verbatimTextOutput("data")
)

server <- function(input, output, session) {
  # 存储PDF页面的原生尺寸信息 用于坐标转换
  page_dims <- reactiveVal()
  # 存储PDF页转成的预览图片
  page_img <- reactiveVal()

  # 加载指定PDF页并转成图片
  observeEvent(input$load_page, {
    req(input$report)
    # 渲染PDF页为图片 dpi可根据精度需求调整
    img_raw <- pdf_render_page(input$report$datapath, page = input$page, dpi = 150)
    img <- png::readPNG(img_raw)
    page_img(img)
    # 获取PDF原生尺寸(单位:点)
    dims <- get_page_dims(input$report$datapath, pages = input$page)
    page_dims(list(width = dims[1], height = dims[2]))
  })

  # 渲染PDF预览图
  output$pdf_preview <- renderPlot({
    req(page_img())
    par(mar = rep(0,4))
    plot(0,0,type="n",xlim=c(0,ncol(page_img())),ylim=c(nrow(page_img()),0),axes=F,xlab="",ylab="")
    rasterImage(page_img(),0,0,ncol(page_img()),nrow(page_img()))
  })

  # 提取表格逻辑
  generate_data <- reactive({
    req(input$pdf_brush, page_dims(), input$report)
    # 把前端框选的像素坐标转换为tabulizer需要的PDF点坐标 格式为c(top, left, bottom, right)
    img_w <- ncol(page_img())
    img_h <- nrow(page_img())
    scale_x <- page_dims()$width / img_w
    scale_y <- page_dims()$height / img_h
    area <- c(
      input$pdf_brush$ymin * scale_y,
      input$pdf_brush$xmin * scale_x,
      input$pdf_brush$ymax * scale_y,
      input$pdf_brush$xmax * scale_x
    )
    table <- extract_tables(
      file = input$report$datapath,
      pages = input$page,
      area = list(area)
    )
    return(table)
  }) %>% bindCache(input$page, input$pdf_brush) %>% bindEvent(input$extract)

  output$data <- renderPrint({
    generate_data()
  })
}

shinyApp(ui = ui, server = server)

部署注意事项

  • 线上服务器需要提前安装Java运行环境以及tabulizer依赖的系统库
  • 如果需要更高精度的框选,可以调高pdf_render_page的dpi参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 07:27:01