1
votes

I built a Google Apps Script (GAS) application tied to a Google Sheet(s) file. The app has these

Code.gs
Example.html

files. This diagram

enter image description here

shows the overall flow for the file save feature I want to build. In the Example.html file, an HTML control calls the saveSheet() function

function saveSheet() {
    google.script.run.withFailureHandler(callBackFailure)
    .withSuccessHandler(getOAuthToken)
    .funcSaveSheet();
}

which immediately calls the Code.gs funcSaveSheet() function, mostly left out in this question to save space.

function funcSaveSheet() {

    .   .   .   .   .
    .   .   .   .   .
    .   .   .   .   .
    .   .   .   .   .

    var blob = response.getBlob().setName(localSpreadSheet.getName() + ' - ' +
        sheet.getName() + '.pdf');

    // This line shows that the function actually writes a file to Google Drive:

    folder.createFile(blob);
    finishedDoc = response.getContent();

    return finishedDoc;
}

The funcSaveSheet() function creates a new file in Google Drive. Note that the funcSaveSheet() function has the

folder.createFile(blob);

line (near the bottom) only to prove that the overall app can write a file to Google Drive. All this works. Now, the one line in the saveSheet() function above

google.script.run.withFailureHandler(callBackFailure)
.withSuccessHandler(getOAuthToken)
.funcSaveSheet();

next calls the function getOAuthToken()

function getOAuthToken(docContentParam) {
    google.script.run.withFailureHandler(showError)
    .withSuccessHandler(createPicker)
    .getOAuthToken1(docContentParam);
  }

also located in the Example.html file. This also works. The GAS app uses all these

google.script.run.withFailureHandler().withSuccessHandler().{function call}

lines because the Google Drive Picker ultimately needs more than one "result set" - not shown here - from more than one Code.gs file function call. Finally, the line in the getOAuthToken() function calls the createPicker() function located in Example.html:

function createPicker(fileParam) {
    if (pickerApiLoaded && OAuthTokenVal) {
        var picker = new google.picker.PickerBuilder()
        .enableFeature(google.picker.Feature.NAV_HIDDEN)
        .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)

    // Use DocsUploadView to upload documents to Google Drive . . .

        .addView(new google.picker.DocsUploadView().setIncludeFolders(true))

    // In this example, the function sets these two values as global
    // variables, but in the actual GAS application, the engineering works
    // differently

        .setOAuthToken(OAuthTokenVal)
        .setDeveloperKey(DEVELOPER_KEY)
        .setCallback(pickerCallback)
        .setOrigin(google.script.host.origin)

    // This does not work
    // .setDocument(fileParam)

        .build();
        picker.setVisible(true);
    } else {
        showError('Unable to load the file picker.');
    }
}

and we come to the problem. The createPicker() function receives the finished, assembled file content built by the earlier call to funcSaveSheet(), as the fileParam parameter. The function builds a Google Picker, but as this screen shot shows

enter image description here

the picker does not know that it should save the file content in / of the fileParam parameter. The picker expects the user to either drag in or drill out to an existing file. Instead, I'd like this function to build a Google Picker that automatically "knows" that it should save the file as passed in / by the fileParam parameter to the function itself. I'd like the Google Picker to clone the behavior of the Microsoft Word / Excel new file save dialog.

I heavily searched - StackOverflow / the Google Picker reference / etc. - but no luck. In the Google Picker reference, I did find what became the

.setDocument(fileParam)

line, here placed near the bottom of the createPicker(fileParam) function. I tried it because it looked promising even though the Google Picker reference does not say much about it and Googling generally told me nothing about it. This line only killed the picker totally. If anyone could guide me on this, I would be most grateful. If I reached for a bridge too far, I'd like to know that as well.

Thank you!

1
The setDocument(document) method is expecting an argument that is a "document" type. The documentation for the document type states: "Document is an enumerated type used to convey information about a specific picked item." The file that you are passing in, is not a picked item. I doubt that the file being passed in, is of the "Document" type. Documentation - document type I'm just guessing, and I really don't know anything about the picker, but that's what I'm thinking.Alan Wells
Thank you, Sandy. Unfortunately, setDocument() did not exactly do what I needed, so I'm still digging.Frank Solomon

1 Answers

0
votes

I figured out a solution. Instead of the Google Picker, I used Google Cloud Print. Full disclosure:

1) Google Cloud Print is in beta as of now

2) It can only see the Google Drive root as a direct file save target location

After saving a file in Drive, however, the user can still move that file within Drive directly.

Read more about this at Bit Vectors . . .