2011-11-10 43 views
1

我正在構建我的第一個使用Google Apps腳本的應用程序。我需要一個允許將文件上傳到Google文檔列表的表單。我現在有根據的Google Apps Script FileUpload docmentation這個工作使用代碼:Google Apps腳本FileUpload()沒有FormPanel?

function doGet(e) { 
    var app = UiApp.createApplication().setTitle("Upload CSV to Sheet"); 
    var form = app.createFormPanel().setId('frm').setEncoding('multipart/form-data'); 
    var formContent = app.createVerticalPanel(); 
    form.add(formContent); 
    formContent.add(app.createFileUpload().setName('thefile')); 
    formContent.add(app.createSubmitButton('Submit')); 
    app.add(form); 
    return app; 
} 

function doPost(e) { 
    // data returned is a blob for FileUpload widget 
    var fileBlob = e.parameter.thefile; 
    var doc = DocsList.createFile(fileBlob); 
    app.close(); 
    return app; 
} 

不過,我想指定我自己的點擊處理程序的提交按鈕,如果可以不等待POST。當我試圖將上面的代碼更改爲這樣的內容時,對e.parameter.thefile的引用爲空,並且不包含文件blob。

function doGet(e) { 

    var app = UiApp.createApplication().setTitle("Upload CSV to Sheet"); 
    var formContent = app.createVerticalPanel(); 
    var submitServerHandler = app.createServerClickHandler('submitHandler_'); 
    formContent.add(app.createFileUpload().setName('thefile')); 
    submitServerHandler.addCallbackElement(formContent); 
    formContent.add(app.createButton('Submit').addClickHandler(submitServerHandler)); 
    app.add(formContent); 
    return app; 
} 

function submitHandler_(e) { 
    // data returned is a blob for FileUpload widget 
    var fileBlob = e.parameter.thefile; 
    var doc = DocsList.createFile(fileBlob); 
    app.close(); 
    return app; 
} 

是否可以在沒有FormPanel的情況下使用FileUpload控件?如果是這樣,怎麼樣?謝謝!

+0

此問題使用不推薦的類,如DocsList。 –

回答

4

您必須使用doPost才能使文件上傳正常工作。您可以將更多點擊處理程序添加到提交按鈕。如果你想在UI上做出快速響應,請使用客戶端處理程序。任何你在表單面板上命名的東西都會在e.parameter中傳遞,你可以像普通的HTML表單那樣使用hiddens。

你想要做什麼?這會幫助我給你更好的答案。

+0

+1感謝您的回答。我的目標是將文件上傳作爲更大數據輸入表單的一部分 - 我希望能夠在用戶單擊「上傳」按鈕而無需提交表單上的其餘數據時上傳文件。 – DrewCo

+1

也許這已經改變,因爲最初的答案 - 上傳可以從'doGet()'工作。 (請參閱[其他答案](http://stackoverflow.com/a/16461925/1677912)。) – Mogsdad

1
function doGet(e) { 
    var app = UiApp.createApplication(); 
    var panel = app.createVerticalPanel().setId('panel'); 
    var fileUpload = app.createFileUpload().setName('theFile').setId('theFile'); 
    var handler = app.createServerChangeHandler('uploadfile'); 
    handler.addCallbackElement(panel); 
    fileUpload.addChangeHandler(handler); 
    panel.add(fileUpload); 
    app.add(panel); 
    return app; 
} 

function uploadfile(e) 
{ 
// data returned which can be used to create a blob 
// assuming mime-type to be a zip file in this example 
    var fileBlob = Utilities.newBlob(e.parameter.thefile, "application/zip","myZippedFile.zip"); 
    var doc = DocsList.createFile(fileBlob); 
    var app = UiApp.getActiveApplication(); 
    app.getElementById('panel').add(app.createLabel('File Uploaded successfully')); 
    return app; 
} 

https://sites.google.com/site/appsscripttutorial/user-interface/upload-doc

+2

我試過這個,它確實創建了一個文件,但該文件是空的,零字節。 'theFile'的e.parameter返回'undefined'。我不認爲這個代碼有效。請證明我錯了,因爲我想找到辦法做到這一點。 –

+2

有一個錯字('thefile'而不是'theFile'),但創建的文件仍然是空的。我的結論是,你必須使用FormPanel來上傳文件。 – Itangalo

0

的另一種方法將文件上載使用createDocsListDialog()。這隻允許從用戶的Google雲端硬盤中選擇文件,但另一方面,您可以使用這些文件做很多事情(包括在沒有FormPanel的情況下使用它們)。

(谷歌的文檔見https://developers.google.com/apps-script/reference/ui/docs-list-dialog

+0

該問題明確指出「......允許將文件上傳到Google文檔列表」。打開已存在於雲端硬盤中的文件不是主題,因此您的答案無關緊要。很抱歉地告訴你,沒有個人冒險;-) –

+0

好點 - 沒有冒犯。 :-) – Itangalo

0

我的文件上傳的工作多一點,我寫了一些輔助功能,創建一個可以以同樣的方式與其他UI使用的「僞控件​​」元素。

我已將它添加到https://github.com/Itangalo/gash的幫助函數集合中,以防它也可以幫助其他人。

如果您在gash.gs從網站添加上面的代碼,你可以管理文件上傳這樣的:

function doGet() { 
    var app = UiApp.createApplication(); 

    // We must have a handler set up before creating the file upload. 
    var handler = app.createServerHandler('handlerCallback'); 
    app.add(gash.createFileUpload('myFile', handler)); 

    app.add(app.createButton('Do something with the file', handler)); 

    return app; 
} 

function handlerCallback(eventInfo) { 
    // The ID of the file in Google Drive is stored in the parameters. 
    var file = DocsList.getFileById(eventInfo.parameter.myFile); 
    // The file was uploaded to the trash. Don't forget to un-trash it. 
    file.setTrashed(false); 

    // Do whatever you want with the file. 
    var app = UiApp.getActiveApplication(); 
    app.add(app.createLabel('Your file size in bytes: ' + file.getSize())); 
    return app; 
} 

還有在後臺FormPanel中,但這種方式我沒有觸摸它。

+0

事實上,你提供的代碼沒有什麼意義......你的幫助函數必須包含在庫中才能像你一樣使用。那麼爲什麼不公開你的圖書館並顯示它的關鍵?或者至少要解釋一下,在使用之前必須先做這件事?你能澄清一下嗎?另外:使用doGet/doPost經典結構有什麼不好的地方?我沒有問題,使用它... :-) –

+0

該庫可在我評論中添加的鏈接,GPL許可證和所有。 (這裏舉例說明如何使用它,而不是解釋它是如何工作的。)它不是一個在GAS上共享的庫,但是如果它足夠成熟就可以。 關於doGet/doPost的煩人的事情,至少對我來說,是我必須以不同於其他輸入(我可以使用標準處理程序管理)來管理文件上傳。此外,這個問題的標題涉及沒有FormPanel的文件上傳。我只是想分享我想出的解決方案。) – Itangalo

+0

不覺得被踩踏...抱歉,如果我的評論是混淆,這不是我的意圖;-)我看了在你的鏈接中,但沒有看到提到這個庫,我主要看了它的代碼,發現當我構建Ui和表單時,(我說過的)從來沒有打擾過我,這是很多工作。我的評論主要是提請注意以下事實:此處顯示的代碼需要將圖書館作爲圖書館收錄,如果沒有圖書館,圖書館將無法使用。 PS:現在我看到我已經在下面評論你的帖子了......你會開始認爲我在「尋找」你(XD),但我不知道!這是一個純粹的巧合,相信我! –