How to create a download button for multiple files

2019-01-27 04:14发布

问题:

I am trying to make a button when clicking, it downloads the files in a zip file. I tried to load the files into the Zip from given url. I am using Liferay 6.1 .

Is the script declaration in the JSP file correct?

I have already specified jszip.js in liferay-portlet.xml.

<footer-portlet-javascript>/js/jszip.js</footer-portlet-javascript>

Do I have to use the Liferay AUI Taglib tag or a simple javaScript tag should do the work?

<aui:script></aui:script> or <script type="text/javascript"></script> or liferay-portlet.xml

Is my script to download multi-files correct?

<c:if test="<%= multi_files_urls != null && multi_files_urls.size() > 1 %>">
    <aui:button onClick="downloadFiles(<%= multi_files_urls %>)" value="Download files"></aui:button>
</c:if>

<script type="text/javascript">
 function downloadFiles(multi_files_urls) {
     for (var url in multi_files_urls )
        JSZipUtils.getBinaryContent(url, function(err, data) {
        if(err) {
            throw err;
        }
        JSZip.loadAsync(data).then(function () {
         var zip = new JSZip(data);
            });
        });

     zip.then(function(content) {
            saveAs(content, "my_documents.zip");
    });
}
</script>

I am getting the following error:

(index):1 Uncaught ReferenceError: zip is not defined at downloadFiles ((index):1) at HTMLInputElement.onclick ((index):1)

Update

I tried <header-portlet-javascript>/js/jszip.js</header-portlet-javascript> and <script type="text/javascript" src="<%=request.getContextPath()%>/js/jszip.js"></script> but it did not work.

I followed this link: Unable to include css and JS files in Liferay Portlet JSP Page

回答1:

I didn't check, but it looks like this is completely independent of Liferay and how you embed the code: The error message says that zip is not defined. The only place where zip is being defined is within this function, and it immediately goes out of scope:

 JSZip.loadAsync(data).then(function () {
    var zip = new JSZip(data);
 });

Thus, it's not in scope when this code runs:

 zip.then(function(content) {
    saveAs(content, "my_documents.zip");
 });

You'd have to declare zip further up, so that it's still in scope when you want to use it (but, most likely, initialize it where you currently initialize). As I have no experience with the JSZip library and the async keyword is used, I'm not sure if it's sufficient to just reorder, or if the timing will only initialize zip after its intended use - I'll leave this up to you.

Try reproducing in a single HTML page, as I don't see the complication that Liferay would bring into the game to be the cause of your problem. This might make it easier to understand. When that runs, embed it in Liferay.



回答2:

Update (The solution)

1- I added js files to liferay-portlet.xml file.

    <footer-portlet-javascript>/js/jquery-1.8.3.min.js</footer-portlet-javascript>
    <footer-portlet-javascript>/js/jszip.js</footer-portlet-javascript>
    <footer-portlet-javascript>/js/jszip-utils.js</footer-portlet-javascript>
    <footer-portlet-javascript>/js/FileSaver.js</footer-portlet-javascript>
    <footer-portlet-javascript>/js/downloader.js</footer-portlet-javascript>
    <footer-portlet-javascript>/js/helpers.js</footer-portlet-javascript>

2- In my view.jsp

<form action="#" id="download_form">
                <% 
                    PortletURL actionURL = renderResponse.createRenderURL(); 
                    List<DLFileEntry> list = (List<DLFileEntry>) request.getAttribute("listFiles");
                    DateFormat dateFormat = new SimpleDateFormat("MMM yyyy");

                    OrderByComparator orderByComparator = OrderByComparatorFactoryUtil.create("DLFileEntry", "modifiedDate", false);
                    Collections.sort(list,orderByComparator);
                %>

                <p class="hide" id="result"></p>
                <aui:button id="download_files" type="submit" value="Download files"></aui:button>

                <liferay-ui:search-container iteratorURL="<%= actionURL %>"
                    delta="10" emptyResultsMessage="no-documents">
                    <liferay-ui:search-container-results total="<%= list.size() %>"
                        results="<%= ListUtil.subList(list, searchContainer.getStart(), searchContainer.getEnd()) %>" />
                    <liferay-ui:search-container-row modelVar="file"
                        className="DLFileEntry">
                        <%
                            ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
                            String pdfUrl = "", excelUrl = "";
                            String logo ="", vendor="", technology="", productType="", flashType="";

                            long globalGroupId = GroupLocalServiceUtil.getCompanyGroup(PortalUtil.getDefaultCompanyId()).getGroupId();

                            if(file.getExtension().equalsIgnoreCase("pdf"))
                                pdfUrl = "<a target='_blank' href='"+ themeDisplay.getPortalURL() + themeDisplay.getPathContext() + "/documents/" + globalGroupId + StringPool.SLASH + file.getUuid()+"' ><img src='/flash-table-portlet/images/pdf.png' width='20px'/> </a>";
                            else if(file.getExtension().equalsIgnoreCase("xlsx") || file.getExtension().equalsIgnoreCase("xls") || file.getExtension().equalsIgnoreCase("csv") )
                                excelUrl = "<a target='_blank' href='"+ themeDisplay.getPortalURL() + themeDisplay.getPathContext() + "/documents/" + globalGroupId + StringPool.SLASH + file.getUuid()+"' ><img src='/flash-table-portlet/images/excel.png' width='20px'/> </a>";

                            try{
                                Map<String, Fields> fieldsMap = file.getFieldsMap(file.getFileVersion().getFileVersionId());
                                for (Fields fields : fieldsMap.values()) {
                                    vendor =  fields.get("vendor").getValue().toString().replace("[\"", "").replace("\"]", "");
                                    if(vendor.equalsIgnoreCase("other"))
                                        logo="<strong>other</strong>";
                                    else
                                        logo = "<img src='/flash-table-portlet/images/vendor/"+vendor.toLowerCase()+".gif' style='max-width:120px' />";
                                    technology= fields.get("technology").getValue().toString().replace("[\"", "").replace("\"]", "");
                                    productType =  fields.get("producttype").getValue().toString().replace("[\"", "").replace("\"]", "");
                                    flashType =  fields.get("flashtype").getValue().toString().replace("[\"", "").replace("\"]", "");
                                }
                            }catch(Exception ex){
                                ex.printStackTrace();
                            }
                        %>

                        <%! String file_name = ""; %>

                        <%
                            String fileUrl = themeDisplay.getPortalURL() + themeDisplay.getPathContext() + "/documents/" + globalGroupId + StringPool.SLASH + file.getUuid();
                            file_name = file.getTitle() + "." + file.getExtension();
                         %>

                        <liferay-ui:search-container-column-text name="Checkbox">
                            <input type="checkbox" data-url="<%= fileUrl %>"
                                name="<%= file_name %>" />
                        </liferay-ui:search-container-column-text>
                        <liferay-ui:search-container-column-text name='date'
                            cssClass="txt-capitalize width-10"
                            value="<%= dateFormat.format(file.getModifiedDate()) %>" />
                        <liferay-ui:search-container-column-text name='vendor'
                            cssClass="width-10" value="<%= logo %>" />
                        <liferay-ui:search-container-column-text name='technology'
                            cssClass="width-10" value="<%= technology %>" />
                        <liferay-ui:search-container-column-text name='product-type'
                            cssClass="width-12" value="<%= productType %>" />
                        <liferay-ui:search-container-column-text name='flash-type'
                            cssClass="width-12" value="<%= flashType %>" />
                        <liferay-ui:search-container-column-text name='model'
                            cssClass="width-25" value="<%= file.getTitle() %>" />
                        <liferay-ui:search-container-column-text name='executive-summary'
                            cssClass="width-10" value="<%= pdfUrl %>" />
                        <liferay-ui:search-container-column-text name='excel-file'
                            cssClass="width-10" value="<%= excelUrl %>" />
                    </liferay-ui:search-container-row>
                    <liferay-ui:search-iterator
                        searchContainer="<%= searchContainer %>"
                        paginate="${fn:length(listFiles) ge 10}" />
                </liferay-ui:search-container>
            </form>

Everything works well !