diff --git a/shiny/uploader/DESCRIPTION b/shiny/uploader/DESCRIPTION
new file mode 100644
index 0000000000000000000000000000000000000000..f6e92c461f806647311cd820dc0d58586b0a09bb
--- /dev/null
+++ b/shiny/uploader/DESCRIPTION
@@ -0,0 +1,7 @@
+Title: Explorando interfaces gráficas interativas no R - 2
+Author: Eduardo E. Ribeiro Jr e Walmes M. Zeviani
+AuthorUrl: https://gitlab.c3sl.ufpr.br/pet-estatistica/iguir2
+License: GPL-3
+DisplayMode: Showcase
+Tags: iguir2
+Type: Shiny
diff --git a/shiny/uploader/server.R b/shiny/uploader/server.R
new file mode 100644
index 0000000000000000000000000000000000000000..989caa601740e89fe3e2464be36504d20e60e56b
--- /dev/null
+++ b/shiny/uploader/server.R
@@ -0,0 +1,99 @@
+library(shiny)
+
+require(xtable)
+
+## Carrega template das aplicações elaboradas pelo projeto iguiR2
+source("../template.R")
+
+rm(list=ls())
+
+# getwd()
+# setwd("/home/walmes/Dropbox/shiny/uploader")
+
+## Cria o diretório caso ainda não exista.
+if(!any(list.files(include.dirs=TRUE)=="files")){
+    dir.create(path="files")
+}
+
+## Interface para subir o arquivo.
+shinyServer(function(input, output){
+    ## Cabeçalho IGUIR2
+    output$header <- renderPrint({
+        template("TEMA")
+    })
+    do <- reactive({
+        inFile <- input$file
+        if(is.null(input$file)){
+            cat(list.files(path="./files"), sep="\n")
+        } else {
+            grrok <- grepl(pattern="^\\d{8}$", x=input$grr)
+            if(!grrok) stop("GRR deve ter 8 digitos numéricos.")
+            fext <- gsub(pattern="^.*(\\.\\w+)$",
+                         x=basename(inFile$name),
+                         replacement="\\1")
+            zipok <- grepl(pattern="\\.(rar|zip)$", x=fext)
+            if(!zipok) stop("Arquivo deve ser zip ou rar.")
+            url <- inFile$datapath
+            file.copy(from=url,
+                      to=paste0(getwd(),
+                                "/files/",
+                                input$turma, "_",
+                                input$grr, "_",
+                                input$trab, fext))
+        }
+        lf <- list.files(path="./files")
+        if (length(lf)>0){
+            setwd("./files")
+            dtinfo <- file.info(list.files(), extra_cols=FALSE)
+            setwd("..")
+            dtinfo <- dtinfo[order(dtinfo$ctime, decreasing=TRUE), c("size","ctime")]
+            dtinfo <- cbind("Arquivo"=rownames(dtinfo), dtinfo)
+            rownames(dtinfo) <- NULL
+            colnames(dtinfo) <- c("Arquivo", "Tamanho", "Criação")
+            if(nrow(dtinfo)==1){
+                dtinfo <- dtinfo[c(1,1),]
+                a <- as.data.frame(sapply(dtinfo, as.character))
+                a <- a[-1,]
+                rownames(a) <- NULL
+            } else {
+                a <- as.data.frame(sapply(dtinfo, as.character))
+                rownames(a) <- NULL
+            }
+            
+            return(list(
+                df2=a[1:min(c(5, nrow(a))),],
+                df3=a,
+                empty=NULL))
+        }
+    })
+    
+    ## Output em tabela.
+    output$table <- renderTable({
+        do()$df2
+    })
+    
+    ## Output em html.
+    output$table <- renderPrint({
+        a <- do()$df2
+        if (is.data.frame(a)){
+            print(xtable(a, align=c("rlrr")), type="html")
+        }
+    })
+    
+    ## Output em 'asis'.
+    output$contents <- renderPrint({
+        do()$empty
+        cat(paste("Um total de", length(list.files(path="./files")), "arquivos."))
+    })
+    
+    #         cat(list.files(path="./files"), sep="\n")
+    
+    ## Output em 'html'.
+    output$html <- renderPrint({
+        do()$empty ## Para ficar reativo.
+        a <- do()$df3
+        if (is.data.frame(a)){
+            print(xtable(a, align=c("rlrr")), type="html")
+        }
+    })
+})
diff --git a/shiny/uploader/ui.R b/shiny/uploader/ui.R
new file mode 100644
index 0000000000000000000000000000000000000000..84b7e5f121b8e4f65d13de7d4f6822f38ce6c8e5
--- /dev/null
+++ b/shiny/uploader/ui.R
@@ -0,0 +1,47 @@
+library(shiny)
+
+## Path do arquivo css.
+css <- ifelse(Sys.info()["nodename"]=="academia",
+              yes="../palatino.css",
+              no="/home/walmes/Dropbox/shiny/palatino.css")
+
+shinyUI(
+    fluidPage(
+        includeCSS(css),
+        ## Cabeçalho IGUIR2
+        htmlOutput("header"),
+        titlePanel("Suba o seu arquivo"),
+        sidebarLayout(
+            sidebarPanel(
+                helpText("Forceça apenas os 8 digitos, ex: 20129999."),
+                textInput(inputId="grr", label="Forneça o seu GRR:", value=""),
+                radioButtons(inputId="turma", label="Turma:",
+                             choices=c("ce083-2015-01",
+                                       "ce063-2015-01",
+                                       "ce213-2015-01")),
+                radioButtons(inputId="trab", label="Trabalho número:",
+                             choices=c(as.character(1:5))),
+                fileInput(inputId="file", label="Selecione o arquivo",
+                          accept=c("application/x-rar-compressed",
+                                   "application/octet-stream",
+                                   "application/zip",
+                                   "application/octet-stream")),
+                submitButton("Upload")
+            ),
+            mainPanel(
+                tabsetPanel(
+                    id='result',
+                    tabPanel(title='Mais recentes',
+                             htmlOutput('table')
+                    ),
+                    tabPanel(title='Todos',
+                             textOutput('contents'),
+                             htmlOutput('html')
+                    )
+                )
+            )
+        )
+    )
+)
+
+