diff --git a/Roadmap.txt b/Roadmap.txt index 3d8886eb..9764ecfd 100644 --- a/Roadmap.txt +++ b/Roadmap.txt @@ -1,6 +1,6 @@ 下一主版本: - 导出看板功能; + ok 导出看板功能; 数据分析添加项目概念,用于分组管理数据集、图表、看板; 表格图表轮播效果; 看板展示页面可显示数据集结果数据; diff --git a/datagear-analysis/src/main/java/org/datagear/analysis/TemplateDashboardWidgetResManager.java b/datagear-analysis/src/main/java/org/datagear/analysis/TemplateDashboardWidgetResManager.java index d2280caf..6b03de7c 100644 --- a/datagear-analysis/src/main/java/org/datagear/analysis/TemplateDashboardWidgetResManager.java +++ b/datagear-analysis/src/main/java/org/datagear/analysis/TemplateDashboardWidgetResManager.java @@ -111,6 +111,15 @@ public interface TemplateDashboardWidgetResManager */ void copyFrom(String id, File directory) throws IOException; + /** + * 将指定{@linkplain TemplateDashboardWidget#getId()}的所有资源拷贝至目标目录。 + * + * @param id + * @param directory + * @throws IOException + */ + void copyTo(String id, File directory) throws IOException; + /** * 是否包含指定名称的资源。 * diff --git a/datagear-analysis/src/main/java/org/datagear/analysis/support/FileTemplateDashboardWidgetResManager.java b/datagear-analysis/src/main/java/org/datagear/analysis/support/FileTemplateDashboardWidgetResManager.java index bef0e56a..65b7252d 100644 --- a/datagear-analysis/src/main/java/org/datagear/analysis/support/FileTemplateDashboardWidgetResManager.java +++ b/datagear-analysis/src/main/java/org/datagear/analysis/support/FileTemplateDashboardWidgetResManager.java @@ -148,6 +148,13 @@ public class FileTemplateDashboardWidgetResManager extends AbstractTemplateDashb IOUtil.copy(directory, myDirectory, false); } + @Override + public void copyTo(String id, File directory) throws IOException + { + File myDirectory = FileUtil.getDirectory(this.rootDirectory, id); + IOUtil.copy(myDirectory, directory, false); + } + @Override public boolean containsResource(String id, String name) { diff --git a/datagear-web/src/main/java/org/datagear/web/controller/AbstractController.java b/datagear-web/src/main/java/org/datagear/web/controller/AbstractController.java index 98b1c399..c7b6e4a9 100644 --- a/datagear-web/src/main/java/org/datagear/web/controller/AbstractController.java +++ b/datagear-web/src/main/java/org/datagear/web/controller/AbstractController.java @@ -4,6 +4,7 @@ package org.datagear.web.controller; +import java.io.IOException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; @@ -17,6 +18,7 @@ import javax.servlet.http.HttpServletResponse; import org.datagear.management.service.DataPermissionEntityService; import org.datagear.persistence.PagingQuery; +import org.datagear.util.IOUtil; import org.datagear.util.JDBCCompatiblity; import org.datagear.util.StringUtil; import org.datagear.web.OperationMessage; @@ -619,6 +621,24 @@ public abstract class AbstractController return pathInfo.substring(index + pathPrefix.length()); } + /** + * 将文件名转换为作为响应下载文件名。 + *

+ * 此方法会对处理中文乱码问题。 + *

+ * + * @param request + * @param response + * @param fileName + * @return + * @throws IOException + */ + protected String toResponseAttachmentFileName(HttpServletRequest request, HttpServletResponse response, + String fileName) throws IOException + { + return new String(fileName.getBytes(RESPONSE_ENCODING), IOUtil.CHARSET_ISO_8859_1); + } + /** * 判断对象、字符串、数组、集合、Map是否为空。 * diff --git a/datagear-web/src/main/java/org/datagear/web/controller/ChartPluginController.java b/datagear-web/src/main/java/org/datagear/web/controller/ChartPluginController.java index 61fbcd31..7fd46362 100644 --- a/datagear-web/src/main/java/org/datagear/web/controller/ChartPluginController.java +++ b/datagear-web/src/main/java/org/datagear/web/controller/ChartPluginController.java @@ -183,7 +183,8 @@ public class ChartPluginController extends AbstractChartPluginAwareController public void download(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model, @RequestParam("id") String[] ids) throws Exception { - response.addHeader("Content-Disposition", "attachment;filename=chartPlugins.zip"); + response.addHeader("Content-Disposition", + "attachment;filename=" + toResponseAttachmentFileName(request, response, "chartPlugins.zip")); response.setContentType("application/octet-stream"); ZipOutputStream zout = IOUtil.getZipOutputStream(response.getOutputStream()); diff --git a/datagear-web/src/main/java/org/datagear/web/controller/DashboardController.java b/datagear-web/src/main/java/org/datagear/web/controller/DashboardController.java index be8ad44c..0a583cf9 100644 --- a/datagear-web/src/main/java/org/datagear/web/controller/DashboardController.java +++ b/datagear-web/src/main/java/org/datagear/web/controller/DashboardController.java @@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -551,6 +552,40 @@ public class DashboardController extends AbstractDataAnalysisController implemen return "/analysis/dashboard/dashboard_form"; } + @RequestMapping("/export") + public void export(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model, + @RequestParam("id") String id) throws Exception + { + User user = WebUtils.getUser(request, response); + + HtmlTplDashboardWidgetEntity dashboard = this.htmlTplDashboardWidgetEntityService.getById(user, id); + + if (dashboard == null) + throw new RecordNotFoundException(); + + TemplateDashboardWidgetResManager dashboardWidgetResManager = this.htmlTplDashboardWidgetEntityService + .getHtmlTplDashboardWidgetRenderer().getTemplateDashboardWidgetResManager(); + + File tmpDirectory = FileUtil.generateUniqueDirectory(this.tempDirectory); + dashboardWidgetResManager.copyTo(dashboard.getId(), tmpDirectory); + + response.addHeader("Content-Disposition", + "attachment;filename=" + toResponseAttachmentFileName(request, response, dashboard.getName() + ".zip")); + response.setContentType("application/octet-stream"); + + ZipOutputStream zout = IOUtil.getZipOutputStream(response.getOutputStream()); + + try + { + IOUtil.writeFileToZipOutputStream(zout, tmpDirectory, ""); + } + finally + { + zout.flush(); + zout.close(); + } + } + @RequestMapping(value = "/delete", produces = CONTENT_TYPE_JSON) @ResponseBody public ResponseEntity delete(HttpServletRequest request, HttpServletResponse response, diff --git a/datagear-web/src/main/java/org/datagear/web/controller/DataController.java b/datagear-web/src/main/java/org/datagear/web/controller/DataController.java index 802704f6..36e662a1 100644 --- a/datagear-web/src/main/java/org/datagear/web/controller/DataController.java +++ b/datagear-web/src/main/java/org/datagear/web/controller/DataController.java @@ -686,8 +686,9 @@ public class DataController extends AbstractSchemaConnTableController } }.execute(); - response.setCharacterEncoding("utf-8"); - response.setHeader("Content-Disposition", "attachment; filename=" + columnName + ""); + response.setCharacterEncoding(IOUtil.CHARSET_UTF_8); + response.setHeader("Content-Disposition", + "attachment; filename=" + toResponseAttachmentFileName(request, response, columnName)); InputStream in = null; OutputStream out = null; @@ -735,7 +736,8 @@ public class DataController extends AbstractSchemaConnTableController @RequestParam("file") String fileName) throws Throwable { response.setCharacterEncoding(RESPONSE_ENCODING); - response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ""); + response.setHeader("Content-Disposition", + "attachment; filename=" + toResponseAttachmentFileName(request, response, fileName)); OutputStream out = null; diff --git a/datagear-web/src/main/java/org/datagear/web/controller/DataExchangeController.java b/datagear-web/src/main/java/org/datagear/web/controller/DataExchangeController.java index fc1c34ae..a9ca230f 100644 --- a/datagear-web/src/main/java/org/datagear/web/controller/DataExchangeController.java +++ b/datagear-web/src/main/java/org/datagear/web/controller/DataExchangeController.java @@ -1319,7 +1319,7 @@ public class DataExchangeController extends AbstractSchemaConnController { response.setCharacterEncoding(RESPONSE_ENCODING); response.setHeader("Content-Disposition", - "attachment; filename=" + new String(fileName.getBytes(RESPONSE_ENCODING), "iso-8859-1") + ""); + "attachment; filename=" + toResponseAttachmentFileName(request, response, fileName)); File directory = getTempDataExchangeDirectory(dataExchangeId, true); File file = FileUtil.getFile(directory, fileName); @@ -1345,7 +1345,7 @@ public class DataExchangeController extends AbstractSchemaConnController { response.setCharacterEncoding(RESPONSE_ENCODING); response.setHeader("Content-Disposition", - "attachment; filename=" + new String(fileName.getBytes(RESPONSE_ENCODING), "iso-8859-1")); + "attachment; filename=" + toResponseAttachmentFileName(request, response, fileName)); File directory = getTempDataExchangeDirectory(dataExchangeId, true); diff --git a/datagear-web/src/main/java/org/datagear/web/controller/DataSetController.java b/datagear-web/src/main/java/org/datagear/web/controller/DataSetController.java index 3cdf3deb..ce385acc 100644 --- a/datagear-web/src/main/java/org/datagear/web/controller/DataSetController.java +++ b/datagear-web/src/main/java/org/datagear/web/controller/DataSetController.java @@ -505,10 +505,10 @@ public class DataSetController extends AbstractSchemaConnController File entityFile = FileUtil.getFile(dataSetDirectory, dataSetEntity.getFileName()); String displayName = dataSetEntity.getDisplayName(); - displayName = new String(displayName.getBytes("UTF-8"), "ISO-8859-1"); - response.setCharacterEncoding("UTF-8"); - response.setHeader("Content-Disposition", "attachment; filename=" + displayName + ""); + response.setCharacterEncoding(IOUtil.CHARSET_UTF_8); + response.setHeader("Content-Disposition", + "attachment; filename=" + toResponseAttachmentFileName(request, response, displayName)); OutputStream out = response.getOutputStream(); IOUtil.write(entityFile, out); diff --git a/datagear-web/src/main/java/org/datagear/web/controller/DriverEntityController.java b/datagear-web/src/main/java/org/datagear/web/controller/DriverEntityController.java index 2057672a..350461af 100644 --- a/datagear-web/src/main/java/org/datagear/web/controller/DriverEntityController.java +++ b/datagear-web/src/main/java/org/datagear/web/controller/DriverEntityController.java @@ -245,7 +245,8 @@ public class DriverEntityController extends AbstractController public void export(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "id", required = false) String[] driverEntityIds) throws Exception { - response.addHeader("Content-Disposition", "attachment;filename=drivers.zip"); + response.addHeader("Content-Disposition", + "attachment;filename=" + toResponseAttachmentFileName(request, response, "drivers.zip")); response.setContentType("application/octet-stream"); ZipOutputStream zout = IOUtil.getZipOutputStream(response.getOutputStream()); @@ -393,8 +394,9 @@ public class DriverEntityController extends AbstractController { DriverEntity driverEntity = this.driverEntityManager.get(id); - response.setCharacterEncoding("UTF-8"); - response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ""); + response.setCharacterEncoding(IOUtil.CHARSET_UTF_8); + response.setHeader("Content-Disposition", + "attachment; filename=" + toResponseAttachmentFileName(request, response, fileName)); OutputStream out = response.getOutputStream(); if (driverEntity != null) diff --git a/datagear-web/src/main/java/org/datagear/web/controller/SqlpadController.java b/datagear-web/src/main/java/org/datagear/web/controller/SqlpadController.java index d854feda..cf60c897 100644 --- a/datagear-web/src/main/java/org/datagear/web/controller/SqlpadController.java +++ b/datagear-web/src/main/java/org/datagear/web/controller/SqlpadController.java @@ -285,8 +285,9 @@ public class SqlpadController extends AbstractSchemaConnController if (!blobFile.exists()) throw new FileNotFoundException(value); - response.setCharacterEncoding("utf-8"); - response.setHeader("Content-Disposition", "attachment; filename=BLOB"); + response.setCharacterEncoding(IOUtil.CHARSET_UTF_8); + response.setHeader("Content-Disposition", + "attachment; filename=" + toResponseAttachmentFileName(request, response, "BLOB")); InputStream in = null; OutputStream out = null; diff --git a/datagear-web/src/main/resources/org/datagear/web/locales/datagear.properties b/datagear-web/src/main/resources/org/datagear/web/locales/datagear.properties index a5626dc8..fed17279 100644 --- a/datagear-web/src/main/resources/org/datagear/web/locales/datagear.properties +++ b/datagear-web/src/main/resources/org/datagear/web/locales/datagear.properties @@ -753,7 +753,7 @@ dashboard.editDashboard=编辑看板 dashboard.viewDashboard=查看看板 dashboard.selectDashboard=选择看板 dashboard.importDashboard=导入看板 -dashboard.name=名称 +dashboard.name=看板名称 dashboard.template=模板内容 dashboard.templateEncoding=HTML模板编码 dashboard.templateName=模板文件名 @@ -762,7 +762,7 @@ dashboard.createTime=创建时间 dashboard.show=展示 dashboard.import.selectFile=选择文件 dashboard.import.desc=文件格式应为:*.html、*.htm、*.zip -dashboard.import.template.desc=多个模板以英文逗号(,)分隔 +dashboard.import.templateName.desc=导入文件中作为看板模板的文件名,应是*.html、*.htm文件,多个模板以英文逗号(,)分隔 dashboard.import.validation.importDashboardFileRequired=请选择看板文件 dashboard.import.templateFileNotExists=导入看板文件中没有找到[{0}]模板文件 dashboard.typeChartIdHere=在此输入图表ID diff --git a/datagear-web/src/main/resources/org/datagear/web/webapp/view/freemarker/analysis/dashboard/dashboard_grid.ftl b/datagear-web/src/main/resources/org/datagear/web/webapp/view/freemarker/analysis/dashboard/dashboard_grid.ftl index 113504ed..55509896 100644 --- a/datagear-web/src/main/resources/org/datagear/web/webapp/view/freemarker/analysis/dashboard/dashboard_grid.ftl +++ b/datagear-web/src/main/resources/org/datagear/web/webapp/view/freemarker/analysis/dashboard/dashboard_grid.ftl @@ -26,14 +26,19 @@ selectOperation 是否选择操作,允许为null <#else> - - +
+ + +
<#if !(currentUser.anonymous)> + @@ -58,8 +63,25 @@ selectOperation 是否选择操作,允许为null (function(po) { $.initButtons(po.element(".operation")); + po.element(".addGroupSelect").selectmenu( + { + appendTo: po.element(), + classes: + { + "ui-selectmenu-button": "ui-button-icon-only splitbutton-select", + "ui-selectmenu-menu": "ui-widget-shadow ui-widget ui-widget-content" + }, + select: function(event, ui) + { + var action = $(ui.item).attr("value"); + + if(action == "importDashboard") + po.open(po.url("import")); + } + }); + po.element(".addGroup").controlgroup(); po.initDataFilter(); - + po.currentUser = <@writeJson var=currentUser />; po.url = function(action) @@ -84,11 +106,6 @@ selectOperation 是否选择操作,允许为null }); }); - po.element("input[name=importButton]").click(function() - { - po.open(po.url("import")); - }); - po.element("input[name=editButton]").click(function() { po.executeOnSelect(function(row) @@ -138,6 +155,16 @@ selectOperation 是否选择操作,允许为null window.open(showUrl, showUrl); }); }); + + po.element("input[name=exportButton]").click(function() + { + po.executeOnSelect(function(row) + { + var data = {"id" : row.id}; + + po.open(po.url("export"), { target: "_blank", data : data }); + }); + }); po.element("input[name=deleteButton]").click( function() diff --git a/datagear-web/src/main/resources/org/datagear/web/webapp/view/freemarker/analysis/dashboard/dashboard_import.ftl b/datagear-web/src/main/resources/org/datagear/web/webapp/view/freemarker/analysis/dashboard/dashboard_import.ftl index 0466fbed..2eb418bf 100644 --- a/datagear-web/src/main/resources/org/datagear/web/webapp/view/freemarker/analysis/dashboard/dashboard_import.ftl +++ b/datagear-web/src/main/resources/org/datagear/web/webapp/view/freemarker/analysis/dashboard/dashboard_import.ftl @@ -13,11 +13,13 @@
- +
-
+
<@spring.message code='select' />
@@ -33,10 +35,12 @@
- +
- +