(一)office文档操作之excel表格模板填充数据导出

前言

java操作excel表格可以使用POI,但是我觉得这些太麻烦了。如果说我想实现合并单元格等操作,可能会更加麻烦。所以我就找到了Xdoc这个第三方API。

一、XDOC

Xdoc官网:http://www.xdocin.com/index.html,具体的使用方法可以自己看看,我就不赘述了。

一、excel模板

在xdoc官网的最下方有一个关于excel的模板,可以下载模板、填充数据后的表格以及实现代码。

但是我想结合springboot 使用,所以还是不能直接使用官方提供的代码的。但是excel模板可以参考一下。

特别注意的是重复数据的第一个单元格一定要加一个批注,这个批注和代码里的参数key值相同,下面会提到。

二、封装工具类

xdoc可以本地jar包调用也可以http请求调用。首先,我们下载官方提供的jar包:http://www.xdocin.com/XDocService.jar,由于maven远程仓库没有响应的jar包,所以就需要我们自己手动打进本地maven仓库,打包命令在以前的博客 SpringBoot使用银联支付 里提到过,可以参考一下。

接下来就是封装一个工具类。

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import com.hg.xdoc.XDocService;
import com.yuyi.lwq.tool.HttpUtils;

public class XdocClient {

	private static final String XDOC_HOST = "http://www.xdocin.com/";
	private static final String XDOC_PATH = "xdoc";
	private static final String KEY = "自己的key";
	
	/**
	 * word文档预览
	 * @param docUrl
	 * @return
	 */
	public static String preview(String docUrl){
		
		return "http://www.xdocin.com/xdoc?_func=to&_format=html&_cache=true&_xdoc="+docUrl;
	}
	
	/**
	 * 转换文档格式
	 * @param docUrl
	 * @return
	 */
	public static String convert(String docUrl,Format format){
		
		String result = null;
		
		Map<String, String> param = new HashMap<String, String>();
		param.put("_func", "to");
		param.put("_key", KEY);
		param.put("_xdoc", docUrl);
		param.put("_format", format.toString());
		//param.put("_to", "d:/b.pdf");
		
		try {
			HttpResponse response = HttpUtils.doGet(XDOC_HOST, XDOC_PATH, null, param);
			HttpEntity entity = response.getEntity();
			int code = response.getStatusLine().getStatusCode();
			if (Objects.equals(code,200)) {
				byte[] byteArray = EntityUtils.toByteArray(entity);
				result = Base64.encodeBase64String(byteArray);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 通过文件模板生成带数据的文件
	 * @param docUrl 文件,可以是本地文件,也可以是网络文件
	 * @param param 文件模板里对应的参数
	 * @param fileName 生成的文件的名字,生成地址为:项目/source/fileName
	 * @return
	 */
	public static boolean localGenerate(String docUrl,Map<String,Object> param,String fileName){
		
		boolean isSuccess = false;
		XDocService service = new XDocService();
		try {
			service.run(docUrl, param, new File(System.getProperty("user.dir")+"/source/"+fileName));
			isSuccess = true;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return isSuccess;
	}
	
	
	public enum Format{
		DOCX{
			@Override
			public String toString() {
				return "docx";
			}
		},
		XLSX{
			@Override
			public String toString() {
				return "xlsx";
			}
		},
		PPTX{
			@Override
			public String toString() {
				return "pptx";
			}
		},
		PDF{
			@Override
			public String toString() {
				return "docx";
			}
		},
		HTML{
			@Override
			public String toString() {
				return "html";
			}
		};
	}
	
}

其中HttpUtil在之前的博客里写过

System.getProperty("user.dir")+"/source/"+fileName 是模板填充数据后生成的文件的位置

三、调用

接下来就可以在service层调用了

	public ResultDTO<JSONObject> download() throws Exception {
		
		//根据类别查询数据并生成json格式字符串
		List<GoodsSaleDTO> breadList = goodsSaleLWQDAO.listAllGoodsSaleByClassify(1);
		String bread = JSONObject.toJSONString(breadList);
		
		List<GoodsSaleDTO> drinkList = goodsSaleLWQDAO.listAllGoodsSaleByClassify(2);
		String drink = JSONObject.toJSONString(drinkList);
		
		List<GoodsSaleDTO> iceList = goodsSaleLWQDAO.listAllGoodsSaleByClassify(3);
		String ice = JSONObject.toJSONString(iceList);
		
		List<GoodsSaleDTO> hotList = goodsSaleLWQDAO.listAllGoodsSaleByClassify(4);
		String hot = JSONObject.toJSONString(hotList);
		
		List<GoodsSaleDTO> otherList = goodsSaleLWQDAO.listAllGoodsSaleByClassify(5);
		String other = JSONObject.toJSONString(otherList);
		
		LocalDate now = LocalDate.now();
		//模板需要的参数
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("日期",LocalDateTimeTool.localDateToString(now, "yyyy年 MM月 dd日"));
		param.put("面包类", bread);
		param.put("饮品类", drink);
		param.put("雪糕类", ice);
		param.put("热饮类", hot);
		param.put("其他", other);
		String fileName = "休闲吧出库单 "+now.toString()+".xlsx";
		boolean isSuccess = XdocClient.localGenerate("模板文件地址", param,fileName);
		if (!isSuccess) {
			return ResultDTO.error(-1);
		}
		
		String pathName = System.getProperty("user.dir")+"/source/"+fileName;
		File file = new File(pathName);
		InputStream in = new FileInputStream(file);
		String result = FileTool.inputStream2String(in);
		
		JSONObject res = new JSONObject();
		res.put("fileName",fileName);
		res.put("file", result);
		
		return ResultDTO.ok(res);
	}

其中输入流转String的工具类如下

public class FileTool {

	public static String inputStream2String(InputStream in) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int len = 0;
        byte[] b = new byte[1024];	
        while ((len = in.read(b, 0, b.length)) != -1) {                     
            baos.write(b, 0, len);
        }
        byte[] buffer =  baos.toByteArray();
        //base64加密
        return Base64.encodeBase64String(buffer);
	}
	
}

这样,先是在工程目录下生成文件,然后用文件输入流读取,再转为字符串。controller层调用后,string转为byte字节数组,直接返给前端页面就可以下载了。

	public ResponseEntity<Object> download()throws Exception{
		
		ResultDTO<JSONObject> result = goodsSaleService.download();
		Integer status = result.getStatus();
		//404
		if (Objects.equals(status,0)) {
			return ResponseEntity.notFound().build();
		}
		//出错
		if (Objects.equals(status, -1)) {
			return ResponseEntity.badRequest().build();
		}
		JSONObject json = result.getData();
		
		byte[] decodeData = Base64.decodeBase64(json.getString("file"));
		HttpHeaders headers = new HttpHeaders();
		headers.setCacheControl("no-cache, no-store, must-revalidate");
	    headers.setContentDispositionFormData("attachment",new String(json.getString("fileName").getBytes("utf-8"), "ISO-8859-1"));
	    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
	    //headers.setContentLength(file.getContentLength());
	    headers.setPragma("no-cache");
	    
	    return new ResponseEntity<Object>(decodeData, headers, HttpStatus.CREATED);
	}

写在最后的话

虽然是可以下载了,但是项目里还会有一份文件,时间长了之后,就会占用空间,所以我们可以写个方法删除或者定期清理。

File rootfile = new File(System.getProperty("user.dir")+"/source");
File[] files = rootfile.listFiles();
if (files.length != 0) {
	for (File file : files) {
		file.delete();
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好,如果你需要使用 VBA 代码导出模板 Excel 表格一对多的数据,可以按照以下步骤操作: 1. 在模板 Excel 表格中,添加一个“数据源”工作表,用于存储需要导出数据。在该工作表中,每行代表一个需要导出表格,每列代表表格中的一个字段。例如,第一列可以是表格名称,第二列可以是表格中的第一个字段,第三列可以是表格中的第二个字段,以此类推。 2. 在模板 Excel 表格中,添加一个“表格模板”工作表,用于存储需要导出表格模板。在该工作表中,可以添加表头、数据行等元素,但是不要添加实际的数据。 3. 编写 VBA 代码,读取“数据源”工作表中的数据,并以此生成多个“表格模板”工作表。具体实现可以使用 For 循环遍历“数据源”工作表中的每一行,并在每行创建一个新的“表格模板”工作表。然后,将“表格模板”工作表中的表头和数据行复制到新创建的工作表中,并将“数据源”工作表中对应行的数据填充到相应的单元格中。 以下是一个简单的示例代码,你可以根据自己的实际需求进行修改和优化: ``` Sub ExportTables() Dim dataSheet As Worksheet Dim templateSheet As Worksheet Dim tableName As String Dim tableData As Range Dim newRow As Range Dim i As Long Set dataSheet = ThisWorkbook.Worksheets("数据源") Set templateSheet = ThisWorkbook.Worksheets("表格模板") For i = 2 To dataSheet.Cells(Rows.Count, 1).End(xlUp).Row tableName = dataSheet.Cells(i, 1).Value Set tableData = dataSheet.Range(dataSheet.Cells(i, 2), dataSheet.Cells(i, dataSheet.Cells(i, Columns.Count).End(xlToLeft).Column)) templateSheet.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count) Set newRow = ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count).Range("A1") newRow.Value = tableName tableData.Copy Destination:=newRow.Offset(1, 0) Next i End Sub ``` 在运行代码之前,请确保已经按照上述步骤创建了“数据源”和“表格模板”工作表,并且将需要导出数据填充到“数据源”工作表中。运行代码后,将会自动创建多个新的工作表,每个工作表代表一个需要导出表格,其中包含了表头和数据行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值