准备xls模板文件:template.xls
要求根据不同的产品型号和图片,插入到模板文件中,然后再填充产品信息。
准备需要替换的图片和数据
功能实现
package net.work.controller.base;import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.work.request.base.BaseProductReq;
import net.work.request.base.ProductExcelReq;
import net.work.service.base.BaseProductService;
import net.work.util.JsonData;
import net.work.util.StoreUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;@RefreshScope
@Api(tags = "成品管理")
@RestController
@RequestMapping("/api/base/v1/product/")
public class BaseProductController {@Value("${product.filePath}")private String filePath;@Autowiredprivate BaseProductService baseProductService;@ApiOperation("产品尺寸图和接线图导入")@PostMapping("importProductImage")public JsonData importProductImage(@RequestParam("file") MultipartFile file, String productModel) throws Exception {return baseProductService.importProductImage(file, filePath, productModel);}@ApiOperation("创建产品规格书xlsx")@PostMapping("createProductExcel")public void createProductExcel(@RequestBody ProductExcelReq productExcelReq) throws Exception {String productModel = productExcelReq.getProductModel();File file1 = new File(filePath + productModel + "\\img1.png");if (!file1.exists()) {throw new Exception("当前产品型号【" + productModel + "】img1.png文件不存在!");}File file2 = new File(filePath + productModel + "\\img2.png");if (!file2.exists()) {throw new Exception("当前产品型号【" + productModel + "】img2.png文件不存在!");}InputStream inputStream1 = new FileInputStream(file1);InputStream inputStream2 = new FileInputStream(file2);Workbook workbook = StoreUtil.createProductExcel(filePath, inputStream1, inputStream2, productExcelReq);ByteArrayOutputStream outputStream = new ByteArrayOutputStream();workbook.write(outputStream);workbook.close();HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();response.setContentType("application/vnd.ms-excel");response.setHeader("Content-Disposition", "attachment;filename=" + productExcelReq.getProductModel() + ".xlsx");OutputStream out = response.getOutputStream();outputStream.writeTo(out);out.flush();out.close();}}
public static Workbook createProductExcel(String filePath, InputStream inp2, InputStream inp3,ProductExcelReq productExcelReq) {String templateName1 = "template1.xlsx";String templateName2 = "template2.xlsx";if (productExcelReq.getLanguage() == 1) {templateName1 = "template1_en.xlsx";templateName2 = "template2_en.xlsx";}try (InputStream inp0 = new FileInputStream(filePath + templateName1);InputStream inp1 = new FileInputStream(filePath + templateName2)) {InputStream inp = inp0;// 可以根据不同的类型决定使用哪个模板if (productExcelReq.getInstallType().contains("xxx")) {inp = inp1;}Workbook workbook = new XSSFWorkbook(inp);Sheet sheet = workbook.getSheetAt(0);{byte[] bytes1 = IOUtils.toByteArray(inp2);byte[] bytes2 = IOUtils.toByteArray(inp3);int pictureIdx1 = workbook.addPicture(bytes1, Workbook.PICTURE_TYPE_PNG);int pictureIdx2 = workbook.addPicture(bytes2, Workbook.PICTURE_TYPE_PNG);CreationHelper helper = workbook.getCreationHelper();Drawing<?> drawing = sheet.createDrawingPatriarch();ClientAnchor anchor1 = helper.createClientAnchor();anchor1.setCol1(2);anchor1.setRow1(6);ClientAnchor anchor2 = helper.createClientAnchor();anchor2.setCol1(5);anchor2.setRow1(18);Picture pict1 = drawing.createPicture(anchor1, pictureIdx1);Picture pict2 = drawing.createPicture(anchor2, pictureIdx2);pict1.resize(4.08, 7.67);pict2.resize(1, 3.05);// 修改单元格内容Row row = sheet.getRow(15);Cell cell = row.getCell(3);cell.setCellValue(productExcelReq.getSpecification());row = sheet.getRow(16);cell = row.getCell(3);cell.setCellValue(productExcelReq.getProductModel());row = sheet.getRow(17);cell = row.getCell(3);cell.setCellValue(productExcelReq.getSwitchType());row = sheet.getRow(18);cell = row.getCell(3);cell.setCellValue(productExcelReq.getWorkDistance());row = sheet.getRow(19);cell = row.getCell(3);cell.setCellValue(productExcelReq.getInstallType());return workbook;}} catch (IOException e) {throw new RuntimeException(e);}}
BaseProductController
类是一个基于Spring框架的RESTful API控制器,用于处理与产品规格书创建和产品图片导入相关的请求。下面将对这个类以及相关功能进行详细的描述。
功能描述
1. 产品尺寸图和接线图导入(importProductImage)
此功能允许用户上传与特定产品型号关联的图像文件。通过向 /api/base/v1/product/importProductImage
发送POST请求,并附带一个MultipartFile对象作为参数,该方法会调用 BaseProductService
的 importProductImage
方法来处理上传的文件,并将其存储在由配置属性 ${product.filePath}
指定的路径下。成功后返回JsonData对象给客户端,其中包含操作结果信息。
2. 创建产品规格书xlsx(createProductExcel)
此功能旨在为指定的产品型号生成一个带有预定义模板格式的Excel文档(xlsx)。它接收JSON格式的数据体,这些数据体包含了要填充到Excel中的产品信息,如型号、语言、安装类型等。具体来说:
- 它首先检查所需的两个PNG图片文件是否存在。
- 然后读取这两个图片文件并创建对应的输入流。
- 接着选择合适的模板文件(根据语言和其他条件),并加载模板。
- 使用Apache POI库创建一个新的工作簿实例,并获取第一个工作表。
- 将提供的图片插入到指定的单元格位置,并调整它们的大小以适应表格布局。
- 更新工作表中的一些单元格内容,比如规格、型号、开关类型、工作距离和安装类型等。
- 最后,将生成的工作簿写入到输出流,并设置响应头以提示浏览器下载生成的Excel文件。
技术细节
- 依赖库:使用了Apache POI来操作Excel文件,
org.apache.poi.ss.usermodel.Workbook
是其核心接口之一。 - 异常处理:当缺少必要的图片文件时,会抛出异常并中断流程。
- 国际化支持:根据传入的语言参数选择不同的模板文件(中文或英文)。
- 多态性:通过判断
installType
来决定使用哪个模板,体现了面向对象编程的多态性原则。 - 资源管理:确保所有打开的资源(如文件输入流)都能正确关闭,避免资源泄漏。
- 安全性:采用了Swagger注解来描述API,便于开发人员理解和测试;同时也遵循了RESTful设计原则。