问题
I have a portal where users sign in and see a bunch of documents sorted and categorized by year then category. They want a check box next to each document so they can select one or many documents then press a button to download all the files from the selected documents.
There is only one file per document.
Is there an easy way to program such a thing?
回答1:
You want to download attachments from selected documents all at once.
Create a zip file which contains all attachments and download the one zip file.
You can find the code for creating a zip file from document's attachments in Naveen Maurya's XSnippet.
Extend this code in a way that you run through all selected documents and grab the attachments from there.
Set a session scope variable with the the Ids of all selected documents in your XPage's button and open XPage zip.xsp (XSnippet's XAgent)
<xp:button
id="button1"
value="Download">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="norefresh">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
var viewPanel = getComponent("viewPanel1");
sessionScope.selectedIds = viewPanel.getSelectedIds();
}]]></xp:this.script>
</xp:executeScript>
<xp:openPage name="/zip.xsp"></xp:openPage>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
Read the Ids from session scope in zip.xsp, get the documents and their attachments and put them all in one zip file.
...
var selectedIds = sessionScope.selectedIds;
for(i=0; i < selectedIds.length; i++) {
var doc:NotesDocument = database.getDocumentByID(selectedIds[i]);
var attachments:java.util.Vector = session.evaluate("@AttachmentNames", doc);
// Loop through all the attachments
for (var i = 0; i < attachments.size(); i++) {
...
As an alternative, you can download all files at once with multiple window.open(url)
on client side:
- collect all attachment's URLs on server side
- write those in a hidden input field
- execute CSJS code in onComplete event to open each URL in a separate window
This is a working example code:
<xp:button
id="button1"
value="Download">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
refreshId="panelDownloadURLs">
<xp:this.action><![CDATA[#{javascript:var viewPanel = getComponent("viewPanel1");
var selectedIDs = viewPanel.getSelectedIds();
var filesToDownload = "";
for(i=0; i < selectedIDs.length; i++) {
var doc:NotesDocument = database.getDocumentByID(selectedIDs[i]);
var attachments:java.util.Vector = session.evaluate("@AttachmentNames", doc);
for (var i = 0; i < attachments.size(); i++) {
var attachment = doc.getAttachment(attachments.get(i).toString());
if (attachment != null) {
filesToDownload += context.getUrl().getAddress().replace(view.getPageName(), '') +
'/0/' + doc.getUniversalID() + '/$FILE/' + attachment.getName() + '#';
}
}
}
getComponent("inputDownloadURLs").setValue(filesToDownload);}]]></xp:this.action>
<xp:this.onComplete><![CDATA[
var filesToDownload = dojo.byId("#{id:inputDownloadURLs}").value.split("#");
for (var i = 0; i < filesToDownload.length; i++) {
if (!filesToDownload[i].toString() == "") {
window.open(filesToDownload[i]);
}
}]]></xp:this.onComplete>
</xp:eventHandler>
</xp:button>
<xp:panel
id="panelDownloadURLs">
<xp:inputHidden
id="inputDownloadURLs"
value=""></xp:inputHidden>
</xp:panel>
But, this alternative solution feels a bit messy if you have a lot of attachments...
回答2:
So I finally figured this out. Using a combination of the zip file code from in Naveen Maurya's XSnippet. and some java code found here. I will post my final code once finished.
It turns out I didn't need to download attached documents rather files from the servers file system.
来源:https://stackoverflow.com/questions/32954221/is-there-a-simple-way-to-allow-a-user-to-download-the-files-in-selected-document