【问题标题】:How to test whether an uploaded Excel file meets requirements如何测试上传的Excel文件是否符合要求
【发布时间】:2017-08-09 09:53:44
【问题描述】:

背景

假设我有一个shiny 应用程序,用户可以在其中上传 Excel 文件。用户将有权访问某个 Excel 模板,我想确保只上传此模板的副本。

我目前的做法

我现在的做法如下:

  1. 检查工作表名称 xyz 是否存在 -> 如果不存在则抛出错误
  2. 从工作表 xyz 中读取数据,将列名与要求进行比较 -> 如果缺少列会引发错误
  3. 重复所有必要的工作表

当前方法存在问题

这需要对所需的工作表名称和所需的列名称进行大量硬编码,并且变得乏味。

问题

所以我的问题是:如何确保用户提供有效文件?您通常使用什么策略来确保您的应用可以正确处理上传的文件?


伪代码

library(shiny)
library(tidyverse)
ui <- fluidPage(fileInput("file", "Upload Excel"))
server <- function(input, output, session) {
    observe({
      req(input$file)
      sheet1 <- tryCatch(read_xlsx(input$file$datapath, sheet = "xyz"),
          error = function(e) {
             ## do some sort of error handling, e.g. write to a reactiveValue list
          })
      if (!all(.REQUIRED_FIELDS_FOR_XYZ %in% names(sheet1))) {
          ## signal error
      }
    })
}

【问题讨论】:

  • 您不能直接使用您的模板作为测试吗?像identical(names(template), names(upload_xlsx)),和床单等一样?
  • 是的,这确实很有帮助。但我必须承认,我有点迷失了使用哪个库。例如,readxl::read_xlsx 的原因是我必须提供工作表名称。在您的提案中:str(template) 会打印出什么?
  • 我使用xlsx 包。在这里,我可以通过提供索引来读取 excel 文件。 xlsx::read.xlsx('test.xlsx', 1) 这会返回一个data.frame,所以str 会打印维度和列名以及数据结构。
  • 其实,你让我走上了正轨。我想我会上传模板文件并从那里导出工作表名称列名等作为模型。如果您费心制定答案,我会很乐意接受,因为您让我走上了正轨。 +1

标签: r shiny


【解决方案1】:

如果您已经在使用 Excel,为什么不使用宏来为您完成工作。考虑列出文件路径、检查格式类型、单元格地址、单元格值等。下面的宏将为您完成大部分繁重的工作。

Sub GetFolder_Data_Collection()

    Dim colFiles As Collection, c As Range
    Dim strPath As String, f, sht As Worksheet
    Dim wbSrc As Workbook, wsSrc As Worksheet
    Dim rw As Range
    Dim sh As Worksheet, flg As Boolean

    Set sht = ActiveSheet

    strPath = ThisWorkbook.Path

    Set colFiles = GetFileMatches(strPath, "*.xlsx", True)

    With sht
        .Range("A:I").ClearContents
        .Range("A1").Resize(1, 5).Value = Array("Name", "Path", "Cell", "Value", "Numberformat")
        Set rw = .Rows(2)
    End With

    For Each f In colFiles
        Set wbSrc = Workbooks.Open(f)
        Set wsSrc = wbSrc.Sheets(1)
        For Each c In wsSrc.Range(wsSrc.Range("A1"), _
                                  wsSrc.Cells(1, Columns.Count).End(xlToLeft)).Cells


            rw.Cells(2).Value = wbSrc.Path
            sht.Hyperlinks.Add Anchor:=rw.Cells(1), Address:=wbSrc.Path, TextToDisplay:=wbSrc.Name
            rw.Cells(3).Value = c.Address(False, False)
            rw.Cells(4).Value = c.Value
            rw.Cells(5).Value = c.NumberFormat

            i = 6
            For Each sh In Worksheets
                If sh.Name Like "Sheet1*" Or sh.Name Like "*Sheet2*" Then rw.Cells(i).Value = sh.Name & " Exists"
                i = i + 1
            Next


            Set rw = rw.Offset(1, 0)
        Next c
        wbSrc.Close False
    Next f
End Sub


'Return a collection of file objects given a starting folder and a file pattern
'  e.g. "*.txt"
'Pass False for last parameter if don't want to check subfolders
Function GetFileMatches(startFolder As String, filePattern As String, _
                    Optional subFolders As Boolean = True) As Collection

    Dim fso, fldr, f, subFldr
    Dim colFiles As New Collection
    Dim colSub As New Collection

    Set fso = CreateObject("scripting.filesystemobject")
    colSub.Add startFolder

    Do While colSub.Count > 0
        Set fldr = fso.GetFolder(colSub(1))
        colSub.Remove 1

        For Each f In fldr.Files
            If UCase(f.Name) Like UCase(filePattern) Then colFiles.Add f
        Next f
        If subFolders Then
            For Each subFldr In fldr.subFolders
                colSub.Add subFldr.Path
            Next subFldr
        End If
    Loop
    Set GetFileMatches = colFiles
End Function

将此代码放入 XLSB 或 XLSM EXCEL 文件中,与您的 EXCEL 文件位于同一文件夹中。

使用 Excel 做这种事情可能更容易,而且我非常支持使用正确的工具来完成这项工作。

【讨论】:

  • +1 表示“为工作使用正确的工具”。但是,我看不出这对我有什么帮助。因为使用 Excel 方法,我可以确保正确填写模板。但我想确保用户确实上传了这个模板的一个实例,而不是任何任意的 Excel 文件。我认为我必须检查问题的shiny 方面。我忽略了什么吗?
  • 我对代码做了一些修改。试试这个版本并反馈。我不知道这是否正是你想要的,但它应该能让你朝着正确的方向开始。
猜你喜欢
  • 2011-02-26
  • 1970-01-01
  • 2012-04-15
  • 2015-03-04
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
相关资源
最近更新 更多