关键词:引出,单据列表
一、需求
引出没有插件,只有引入有插件。
在引出时可能需要修改一些列头的样式风格,在引出时做一些对引出数据的修改。
我们需要一个更加自由地,自定义程度更高的方式去引出数据,并且在引出数据时,还能做到多个单据数据组合来引出。
在案例中,我并没有获取其他单据标识对应的单据的数据,但是理论上是可以实现:引出时,引出不同单据标识的数据。
只需要使用QueryServiceHelper查询其他单据标识,再按照上面的实现思路去导出数据。
单元格高度,单元格背景色,文字字体/颜色/字号 等等风格的定义,这些风格样式都可以通过
XSSFWorkbook来实现,关于工作簿
XSSFWorkbook类的一些具体用法,请各位开发者自行搜索。
二、思路与方案
实现思路是:
获取选择的列表数据,然后构造工作簿,使用工作簿生成输出流,再转成输入流,最后用调用文件服务,把输入流上传到文件服务器。
1. 创建java插件
2. 单据列表工具栏添加按钮,添加单据体列表插件
3. 编写java插件,分为几步:
3.1 获取已选数据,构造查询字段,QueryServiceHelper查询获取数据
3.2 构造XSSFWorkbook,构造行XSSFRow,构造单元格XSSFCell
3.3 把选择的数据填入
XSSFWorkbook里面的单元格
XSSFCell
3.4 构造OutputStream实例,把
XSSFWorkbook写入
OutputStream
3.5
OutputStream转为InputStream
3.6 创建文件路径,文件名,调用FileService的upload,把
InputStream上传到文件服务器
3.7 弹出下载链接弹框
三、实现过程
1.新建单据列表插件
2.单据列表设计器
注册插件
添加按钮
3.编写插件
3.1获取已选数据,构造查询字段,QueryServiceHelper查询获取数据
/**
* @param entityName 单据标识
* @param listColumns 列
* @param selectedRows 已选行
* @return
private DynamicObjectCollection queryData(String entityName, List<IListColumn> listColumns, ListSelectedRowCollection selectedRows) {
StringBuilder stringBuilder = new StringBuilder();
// 构造查询字段
for (int i = 0; i < listColumns.size(); i++) {
IListColumn listColumn = listColumns.get(i);
if (!listColumn.getListFieldKey().equals("fseq")) {
if (i == listColumns.size() - 1) {
stringBuilder.append(getFieldKey(entityName, listColumn));
} else {
stringBuilder.append(getFieldKey(entityName, listColumn) + ", ");
String selectFields = stringBuilder.toString();
// 构造idList,获取已选行的id,之后作为过滤条件去查询数据
List<Long> idList = new ArrayList<>();
for (ListSelectedRow row : selectedRows) {
idList.add((Long) row.getPrimaryKeyValue());
// QFilter的过滤条件为:单据id等于idList里面的这些id才符合获取条件,其他的数据不获取
QFilter qFilter = new QFilter("id", QFilter.in, idList);
// 查询数据
DynamicObjectCollection dynamicObjectCollection =
QueryServiceHelper.query(entityName, selectFields, qFilter.toArray());
/*DynamicObject[] dynamicObjectArray =
BusinessDataServiceHelper.load(entityName, selectFields, qFilter.toArray());*/
return dynamicObjectCollection;
}
3.2构造XSSFWorkbook,构造行XSSFRow,构造单元格XSSFCell
合并第一行为标题
// 创建标题
XSSFRow headRow = sheet.createRow(0);
XSSFCell headCell = headRow.createCell(0);
headCell.setCellValue(title);
XSSFCellStyle setBorder = workbook.createCellStyle();
setBorder.setFillForegroundColor(new XSSFColor(Color.RED));// 设置背景色
headCell.setCellStyle(setBorder);
// 合并第1行的前几列,合并列数 = excel的列数
CellRangeAddress titleCellAddresses = new CellRangeAddress(0, 0, 0, excel.get(0).size() - 1);
sheet.addMergedRegion(titleCellAddresses);
构造
XSSFCell
//写入数据
for (int i = 0; i < excel.size(); i++) {
XSSFRow nrow = sheet.createRow(i + 1);
for (int u = 0; u < excel.get(i).size(); u++) {
XSSFCell ncell = nrow.createCell(u);
ncell.setCellValue(excel.get(i).get(u));
}
3.3把选择的数据填入XSSFWorkbook里面的单元格XSSFCell,设置风格样式
/**
* excel生成
* @param excel 数据源,List<List<String>>,外层的list是行,里面的List<String>是列,存储value
* excel.size()是行数,excel.get(n).size()是列数
* @return
private XSSFWorkbook excel(List<List<String>> excel, String title) {
//创建excel工作簿
XSSFWorkbook workbook = new XSSFWorkbook();
//创建工作表sheet
XSSFSheet sheet = workbook.createSheet();
//设置默认列宽
sheet.setDefaultColumnWidth(20);
// 创建标题
XSSFRow headRow = sheet.createRow(0);
XSSFCell headCell = headRow.createCell(0);
headCell.setCellValue(title);
// 设置首行标题的一些风格样式
XSSFCellStyle titleStyle = workbook.createCellStyle();
// 设置背景色
//设置填充方案
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// 正红色
//setBorder.setFillForegroundColor(new XSSFColor(Color.RED));
// 设置自定义填充颜色,天蓝色
titleStyle.setFillForegroundColor(new XSSFColor(new Color(135,206,250)));
// 设置水平居中
titleStyle.setAlignment(HorizontalAlignment.CENTER);
// 设置垂直居中
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置字
XSSFFont font = workbook.createFont();
// 字体颜色橘红色
font.setColor(new XSSFColor(new Color(255 ,69,0)));
// 设置字号
font.setFontHeight(20);
// 设置字体
font.setFontName("微软雅黑");
titleStyle.setFont(font);
headCell.setCellStyle(titleStyle);
// 合并第1行的前几列,合并列数 = excel的列数
CellRangeAddress titleCellAddresses = new CellRangeAddress(0, 0, 0, excel.get(0).size()-1);
sheet.addMergedRegion(titleCellAddresses);
// 单据列表数据风格样式,设置字体为黑体,字号15
XSSFCellStyle billStyle = workbook.createCellStyle();
XSSFFont billFont = workbook.createFont();
billFont.setFontName("黑体");
billFont.setFontHeight(15);
billStyle.setFont(billFont);
//写入单据列表数据
for (int i = 0; i < excel.size(); i++) {
// i+1是因为前面第1行加了一个标题,单据列表数据是从Excel的第2行开始的,所以要+1
XSSFRow nrow = sheet.createRow(i+1);
for (int u=0;u<excel.get(i).size();u++){
XSSFCell ncell = nrow.createCell(u);
ncell.setCellStyle(billStyle);
ncell.setCellValue(excel.get(i).get(u));
return workbook;
}
3.4构造OutputStream实例,把XSSFWorkbook写入OutputStream
OutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
3.5OutputStream转为InputStream
public ByteArrayInputStream parse(final OutputStream out) throws Exception {
ByteArrayOutputStream baos = (ByteArrayOutputStream) out;
final ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
return swapStream;
}
3.6创建文件路径,文件名,调用FileService的upload,把InputStream上传到文件服务器
private String upload(String entityName, XSSFWorkbook workbook) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
String fileName = entityName + sdf.format(new Date()) + ".xlsx";
String pathName = "/offices/" + fileName;
try {
OutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
InputStream inputStream = parse(outputStream);
FileService fs = FileServiceFactory.getAttachmentFileService();
String path = fs.upload(new FileItem(fileName, pathName, inputStream));
return path;
} catch (Exception e) {
System.out.println(e.getMessage());
return "";
}
3.7 弹出下载链接弹框
// 弹出提示框
getView().showMessage("下载文件链接:" + RequestContext.get().getClientFullContextPath() + "/attachment/download.do?path=" + path);
3.8 如果需要直接下载链接,可以用openUrl方法,在浏览器中打开新页签,访问下载链接。
这样浏览器就会直接下载这个excel文件。
getView().openUrl(RequestContext.get().getClientFullContextPath() + "/attachment/download.do?path=" + path)
四、效果图
打开Excel文件,效果如下,
五、开发环境版本
六、注意事项
异常场景
(1)在上传时,遇到了抛异常的场景,文件服务拒接连接。
可以从以下方向排查问题:
七、参考资料
【开发平台】指导手册
学习成长中心
插件开发
八、
附件
附件包含补丁包和java源代码。
补丁包包含jar包和元数据包,
请在mc中安装补丁包。
附件里的案例和本文的一些截图,在界面上略有差异,但实现方式是一致的。
插件代码: FruitOutPutListPlugIn.java,已上传至附件.