背景
Confluence是现在广泛使用的团队协作文档系统。虽然自身带了一些表格编辑功能,但表格的整体功能较弱,比如不能通过Excel文件进行导入导出,表格在复制到Excel时格式会比较奇怪等等。对于未完全整合流程到Confluence上的团队,信息从Excel到在线文档系统的流转是个巨大的工作量。
介绍
Elements Spreadsheet作为Confluence的插件可以有效的解决上面的部分问题,通过这个插件可以接近完美导入导出Excel到Confluence系统中(试了Excel太大的话会莫名其妙的编辑中崩溃),Excel文档可以完美嵌入到Confluence的网页中,同时支持在线编辑与占用提示,公式等等功能,参考Confluence的介绍与文档。Elements Spreadsheet for Confluence | Atlassian Marketplace
安装步骤
整个安装步骤参考Confluence安装Drawio插件 - MrHeartTired (ltang.me)
-
首先在官方链接下载当前版本支持的插件。(前面的官方链接进入Version页面选择)
-
其次,再IDE(Idea)中新建如下文件与对应的包目录:
AbstractSpreadsheetRestService.java文件与对应的包目录。
package com.valiantys.software.spreadsheets.rest; import com.atlassian.upm.api.license.PluginLicenseManager; import com.valiantys.software.spreadsheets.rest.model.ErrorModel; import com.valiantys.software.spreadsheets.service.error.ErrorType; import com.valiantys.software.spreadsheets.service.error.SpreadsheetError; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; public abstract class AbstractSpreadsheetRestService { public static final String ATLASSIAN_DEV_MODE = "atlassian.dev.mode"; private final PluginLicenseManager pluginLicenseManager; protected AbstractSpreadsheetRestService(PluginLicenseManager pluginLicenseManager) { this.pluginLicenseManager = pluginLicenseManager; } protected boolean isLicenseValid() { return true; } private boolean isDevMode() { String devMode = System.getProperty("atlassian.dev.mode"); return Boolean.parseBoolean(devMode); } protected ErrorModel toErrorModel(SpreadsheetError error) { return new ErrorModel(error.getMessage()); } protected Response toResponse(SpreadsheetError error) { ErrorType type = error.getType(); if (type == ErrorType.DATA_CONVERSION_ERROR) { return Response.status(Status.BAD_REQUEST).entity(new ErrorModel(error.getMessage())).build(); } else if (type == ErrorType.FORBIDDEN) { return Response.status(Status.FORBIDDEN).entity(new ErrorModel(error.getMessage())).build(); } else if (type == ErrorType.MISSING_DATA) { return Response.status(Status.NOT_FOUND).entity(new ErrorModel(error.getMessage())).build(); } else { return type == ErrorType.INVALID_REQUEST ? Response.status(Status.BAD_REQUEST).entity(new ErrorModel(error.getMessage())).build() : Response.status(Status.INTERNAL_SERVER_ERROR).entity(new ErrorModel(error.getMessage())).build(); } } protected String getCharset(HttpServletRequest request) { String characterEncoding = request.getCharacterEncoding(); return characterEncoding == null ? "UTF-8" : characterEncoding; } }
ErrorModel文件与对应的包目录
package com.valiantys.software.spreadsheets.rest.model; public class ErrorModel { private String message; public ErrorModel() { } public ErrorModel(String message) { this.message = message; } public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } }
ErrorType文件与对应的包目录
package com.valiantys.software.spreadsheets.service.error; public enum ErrorType { DATA_CONVERSION_ERROR, FORBIDDEN, INVALID_REQUEST, INTERNAL_ERROR, MISSING_DATA; private ErrorType() { } }
SpreadsheetError文件与对应的包目录
package com.valiantys.software.spreadsheets.service.error; import javax.ws.rs.core.Response; public class SpreadsheetError { private ErrorType type; private String message; public SpreadsheetError() { } public SpreadsheetError(ErrorType type) { this.type = type; } public SpreadsheetError(ErrorType type, String message) { this.type = type; this.message = message; } public static SpreadsheetError build(ErrorType type) { return new SpreadsheetError(type); } public static SpreadsheetError build(ErrorType type, String message) { return new SpreadsheetError(type, message); } public ErrorType getType() { return this.type; } public void setType(ErrorType type) { this.type = type; } public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } public String toString() { return "Error " + this.type.name() + ": " + this.message; } public Response build() { return null; } }
这一步中只有第一个AbstractSpreadsheetRestService编译出来的的class文件是需要的,其他只是为了解决编译报错。
- 在刚安装的jdk环境下,以下两个包会提示找不到,这两个包理论上是可以直接导入的
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status;
但是由于我对java不太熟悉,java环境都是新装的,所以这两个包我也是按步骤1的方式,补的文件用来编译。
Response文件与对应的包目录。
package javax.ws.rs.core; import java.lang.annotation.Annotation; import java.net.URI; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; public abstract class Response { protected Response() { } public static ResponseBuilder status(Status status) { return null; } public interface StatusType { } public enum Status implements Response.StatusType { BAD_REQUEST, FORBIDDEN, NOT_FOUND, INTERNAL_SERVER_ERROR, } }
ResponseBuilder文件与包目录。
package javax.ws.rs.core; import com.valiantys.software.spreadsheets.rest.model.ErrorModel; import com.valiantys.software.spreadsheets.service.error.SpreadsheetError; public class ResponseBuilder { public SpreadsheetError entity(ErrorModel errorModel) { return null; } }
不要在意具体的代码逻辑与包关系,目的只是为了编译AbstractSpreadsheetRestService.class。同样PluginLicenseManager与LicenseService也需要像参考文章一样补出,这里由于没有代码就不列出来了。
替换与安装
文件编辑完成后,使用7z打开elements-spreadsheet.obr文件,替换AbstractSpreadsheetRestService.class文件并保存。然后按参考文章的方式上传到Confluence安装即可(使用管理员账号登录confluence,找到插件管理 -> 上传插件 -> 选择修改后的obr包,点击上传)。安装成功后,虽然显示试用,但是这时候就已经可以在Confluence中导入并保存Excel文件了,真实的试用状态下Excel导入后是无法保存的。到此安装完成,可以尽情在网页中编辑Excel了。