电子表格FineReport教程:[29]文件控件示例
1、描述
填报报表中,使用文件控件上传文件,可以通过公式获取文件名称,文件类型和文件大小,
filename(file):获取文件名称;
filetype(file):获取文件类型;
filesize(file) :获取文件大小。
单文件上传时,上面3个公式返回值均为字符串,多文件上传时,返回值为数组。
2、filename(file)
filename是获取文件名称。
如下图,新建一张模板,在B2单元格中添加一个文件控件,并在C2单元格中输入公式=filename(B2),获取上传文件的名:
注:如果上传多文件,则filename获取的是所有文件的名称,中间用逗号隔开,返回值数据类型为数组,如上传2个文件A.xls和B.txt,那么filename的返回值则为["A.xls","B.txt"]
![电子表格FineReport教程:[29]文件控件示例](https://exp-picture.cdn.bcebos.com/40d2d0e8b004541bdb8d1695869a310e1699a6d5.jpg)
3、filetype(file)
filetype是获取文件类型
file : 为文件控件或者文件所在单元格,当file为单文件时,返回文件类型字符串;当file为多文件时,返回文件类型数组;当file不是文件类型,返回错误信息。
4、 单文件
如上模板,在D2单元格中输入=filetype(B2),并将文件控件设为只支持单文件上传,填报预览模板,点击文件控件上传一个jpg文件,效果如下图:
获取到了文件控件的文件类型jpg,由于上传的是单文件,故返回的是字符串类型数据。
![电子表格FineReport教程:[29]文件控件示例](https://exp-picture.cdn.bcebos.com/bbf95c406afec314e547715dcac1b727ad539cd5.jpg)
5、多文件
如上模板,去掉文件控件只支持单文件上传前面的勾选,填报预览模板,点击文件控件,选中3个文件,效果如下图:
filename(B2)返回值为数组,数组数据为["激活码.txt","GWY.txt","chinanet.jpg"],filetype(B2)也是返回数组类型,返回值为["txt","txt","jpg"]
![电子表格FineReport教程:[29]文件控件示例](https://exp-picture.cdn.bcebos.com/07c98f2ca5cadce88dcae44ffcf7980e5e2095d5.jpg)
6、filesize(file)
filesize(file)是获取文件大小,单位为KB。
file : 为文件控件或者文件所在单元格,当file为单文件时,返回文件类型字符串;当file为多文件时,返回文件类型数组;当file不是文件类型,返回错误信息。
类似于filetype,单文件上传时,filesize返回值为字符串,多文件上传,则返回数组。
在E2输入公式=filesize(B2),填报预览模板,效果如下图:
![电子表格FineReport教程:[29]文件控件示例](https://exp-picture.cdn.bcebos.com/76b6860e5f2043717c59d293323acd8921c58fd5.jpg)
1、问题描述
在使用文件上传控件时,希望将文件上传放到某个固定的位置下并且就将上传的文件名提交入库,此时要如何实现呢?
2、实现思路
通过自定义函数实现文件上传到指定路径,然后通过在按钮的自定义事件(填报自定义事件)中将数据提交入库并调用此自定义函数即可。
3、编写自定义函数
Commit3.java源文件代码具体如下:
package com.fr.data;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.*;
import com.fr.base.FRContext;
import com.fr.base.Formula;
import com.fr.cache.Attachment;
import com.fr.data.ClassSubmitJob;
import com.fr.data.SubmitJob;
import com.fr.data.impl.SubmitJobValue;
import com.fr.general.FArray;
import com.fr.general.FRLogManager;
import com.fr.general.FRLogger;
import com.fr.script.Calculator;
import com.fr.stable.UtilEvalError;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLableReader;
public class Commit3 implements SubmitJob {
private Object attach;
private SubmitJobValue filePath; //定义文件路径
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public void doJob(Calculator ca) throws Exception {
FRContext.getLogger().info("begin to upload file...");
final Object attachO = attach;
if (attachO instanceof FArray && ((FArray) attachO).length() != 0) {
new Thread() {
public void run() {
int i;
FArray attachmentlist = (FArray) attachO;
for (i = 0; i < attachmentlist.length(); i++) {
if (!(attachmentlist.elementAt(i) instanceof Attachment)) {
continue;
} else {
FRContext.getLogger().info("filePath.value:" + filePath.getValue().toString());
FRContext.getLogger().info("filePath.valueState:" + filePath.getValueState() +
"注:valueState 0,1,2,3 分别表示 默认值,插入行,值改变,删除行");
String FilePath = filePath.getValue().toString();
String FileName = ((Attachment) (attachmentlist.elementAt(i))).getFilename();
String Path = FilePath + "\\" + FileName;
File fileDir = new File(FilePath);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
try {
mkfile(FilePath, FileName, new java.io.ByteArrayInputStream(
((Attachment) (attachmentlist.elementAt(i))).getBytes())); //新建文件夹,并且写入内
} catch (Exception e) {
Logger.getLogger("FR").log(Level.WARNING,
e.getMessage() + "/nmkfileerror", e);
}
}
}
}
}.start();
}
}
private static void mkfile(String path, String FileName,
java.io.InputStream source) throws FileNotFoundException,
IOException {
File fileout = new File(path, FileName);
if (fileout.exists()) {// 检查是否存在
fileout.delete();// 删除文件
FRContext.getLogger().info("old file deleted");
}
// 在当前目录下建立一个名为FileName的文件
if(fileout.createNewFile()) {
FRContext.getLogger().info(path + FileName + "created!!");
}
FileOutputStream outputStream = new FileOutputStream(fileout);
byte[] bytes = new byte[1024];
int read=source.read(bytes);
while (read!=-1) {
outputStream.write(bytes, 0, read);
outputStream.flush();
read = source.read(bytes);
}
outputStream.close(); //把source写入新建的文件
}
public void readXML(XMLableReader reader) {
// TODO Auto-generated method stub
}
public void writeXML(XMLPrintWriter writer) {
}
@Override
public void doFinish(Calculator arg0) throws Exception {
// TODO Auto-generated method stub
}
}
4、编译自定义函数
将编译后的Commit3.class和Commit3$1.class放在FineReport的安装目录WEB-INF下面的classes目录下,由于Commit3.java属于包com.fr.data,因此Commit3.class和Commit3$1.class需要放置在classes\com\fr\data目录下。
5、定义模板
表样设置
按照下图设置表样:
A1单元格的控件类型为文件上传控件,控件名为attach;B1单元格的控件类型为按钮,按钮名字为上传,点击该按钮时,将文件上传;C1单元格的控件类型为文本框,获取上传文件名称,使用公式filename(A1);在D1单元格中输入文件要上传的路径,控件设置为不可见。
![电子表格FineReport教程:[29]文件控件示例](https://exp-picture.cdn.bcebos.com/3761a73acd8920c50e8d6c86568a59de440788d5.jpg)
6、自定义函数调用及入库处理
给B1按钮增加个点击事件,选择提交入库,进行如下图设置:
![电子表格FineReport教程:[29]文件控件示例](https://exp-picture.cdn.bcebos.com/274e9635dd8a59de69856cb2b370d5413b8c84d5.jpg)
7、设置后,点击设置提交事件按钮,然后增加自定义提交事件,点击“+”按钮,选择自定义事件,然后选择com\fr\data\commit3.class,点击增加属性按钮,添加2个属性,名字分别为attach和filePath(与commit3.java中定义的文件路径名相同),值选择分别为公式A1和单元格D1,其效果如下图:
注:由于attach在Commit3.java中定义的是object对象,所以其属性值只能是公式F(x)=A1,不能选择单元格,然后输入A1,而filePath在Commit3.java中定义的是SubmitJobValue,所以其属性值类型只能是单元格,然后选择具体对应的哪个单元格,如上图的形式,不能写公式。
![电子表格FineReport教程:[29]文件控件示例](https://exp-picture.cdn.bcebos.com/3bcdb808a50f94fc640e7f7d4cf88a775cddfcd5.jpg)