记一次动态导出excel并且转pdf的辛酸史。

前言:接到一个需求,需要把用户填写的资料,填写excel模板中。并且导出pdf

收到需求后,着手开干。

1.先将数据填写到excel
1.1. 选取了esaypoi 框架 ,因为该框架支持excel模板填充数据,只需要定义好参数,会根据设定的参数填充数据。并且支持 循环插入数据。操作简单。

但是,这个框架有个巨坑的地方。多个fe 标签。就会出现莫名其妙的BUG,,会报【for each 当中存在空字符串,请检查模板】。整整花了2
天的时间,后面实在没办法。直接放弃。
1.2.上面的框架不支持后,把目光转向了阿里的esayExcel 。但是发现它对单元格的合并很不友好。加上升级框架对于现有项目的改动很大,然后放弃。
1.3.最后,在同事的帮助下,找到了Jxls 。强大的嵌套循环支持,简易的语法。后面  数据成功填写到了excel。

附上导包jxls 的pom.xml

                <!-- jxls begin -->
        <dependency>
            <groupId>org.jxls</groupId>
            <artifactId>jxls</artifactId>
            <version>2.8.0</version>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.jxls</groupId>
            <artifactId>jxls-poi</artifactId>
            <version>2.8.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi-ooxml</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.jxls</groupId>
            <artifactId>jxls-jexcel</artifactId>
            <version>1.0.9</version>
        </dependency>

        <!--根据jxls-cor-1.0.6修改,支持poi4.x版本-->
        <dependency>
            <groupId>net.sf.jxls</groupId>
            <artifactId>jxls-core</artifactId>
            <version>1.0.4</version>
        </dependency>

附上工具类

import org.jxls.common.Context;
import org.jxls.transform.Transformer;
import org.jxls.util.JxlsHelper;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

public class JxlsUtils{
     
    private static final String TEMPLATE_PATH="jxls-template";
     
    public static void exportExcel(InputStream is, OutputStream os, Map<String, Object> model) throws IOException {
        Context context = new Context();
        if (model != null) {
            for (String key : model.keySet()) {
                context.putVar(key, model.get(key));
            }
        }
        JxlsHelper jxlsHelper = JxlsHelper.getInstance();
        Transformer transformer  = jxlsHelper.createTransformer(is, os);
        //JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator)transformer.getTransformationConfig().getExpressionEvaluator();
        //Map<String, Object> funcs = new HashMap<>();
      //  funcs.put("utils", new JxlsUtils());    //添加自定义功能
      //  evaluator.getJexlEngine().setFunctions(funcs);
        jxlsHelper.processTemplate(context, transformer);
    }
 
    public static void exportExcel(File xls, File out, Map<String, Object> model) throws FileNotFoundException, IOException {
            exportExcel(new FileInputStream(xls), new FileOutputStream(out), model);
    }
     
    public static void exportExcel(String templateName, OutputStream os, Map<String, Object> model) throws FileNotFoundException, IOException {
        File template = getTemplate(templateName);
        if(template!=null){
            exportExcel(new FileInputStream(template), os, model);    
        }
    }
     
     
    //获取jxls模版文件
 
    public static File getTemplate(String name){
        String templatePath = JxlsUtils.class.getClassLoader().getResource(TEMPLATE_PATH).getPath();
        File template = new File(templatePath, name);
        if(template.exists()){
            return template;
        }
        return null;
    }    
     
    // 日期格式化
    public String dateFmt(Date date, String fmt) {
        if (date == null) {
            return "";
        }
        try {
            SimpleDateFormat dateFmt = new SimpleDateFormat(fmt);
            return dateFmt.format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
     
    // if判断
    public Object ifelse(boolean b, Object o1, Object o2) {
        return b ? o1 : o2;
    }
     
}

 

 

2.excel转pdf

1.1.一开始使用的是Spire ,功能强大,直接几行代码转DF, 但是免费版只能转3页,超过3页会出现提示。。。
1.2.最后找到了aspose ,完美解决问题!!!!!

附上asposepom.xml(ps:这个jar需要自己下载下俩,然后放到项目里面引用的。)

<dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-cells</artifactId>
            <version>8.5.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/../file/lib/aspose-cells-8.5.2.jar</systemPath>
        </dependency>

附上导出代码——将上面的excel转换成PDF

Map<String, Object> map = new HashMap<String, Object>();
        //设置参数,excel是模板填充
        map.put("services",service);
        // excel 路径
        URL url=new URL("http://xxxxxxxx);
        
        String fileName = URLEncoder.encode("文件名.pdf", CharsetUtil.UTF_8);
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        response.setContentType("application/octet-stream;charset=UTF-8");
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();


        InputStream inputStream1 = url.openStream();
        log.info("开始导出excel============================时间为:"+DateUtil.format(new Date(),"yyyy-MM-dd HH:ss:mm"));
        JxlsUtils.exportExcel(inputStream1,outputStream,map);
        log.info("结束导出excel============================时间为:"+DateUtil.format(new Date(),"yyyy-MM-dd HH:ss:mm"));
        

        log.info("开始导出pdf============================时间为:"+DateUtil.format(new Date(),"yyyy-MM-dd HH:ss:mm"));
        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        ServletOutputStream responseOutputStream = response.getOutputStream();
        Excel2Pdf.excel2pdf(inputStream,responseOutputStream);

        log.info("结束导出pdf============================时间为:"+DateUtil.format(new Date(),"yyyy-MM-dd HH:ss:mm"));

        responseOutputStream.flush();
        responseOutputStream.close();
        inputStream.close();
        inputStream1.close();
        outputStream.flush();
        outputStream.close();

补上 Excel2Pdf 工具类

import com.aspose.cells.License;
import com.aspose.cells.SaveFormat;
import com.aspose.cells.Workbook;

import javax.servlet.ServletOutputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 * @author MRHuang
 * @version 1.0.0
 * @ClassName Excel2Pdf
 * @Description
 * @createTime 2022年10月23日
 */
public class Excel2Pdf {

    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = Excel2Pdf.class.getClassLoader().getResourceAsStream("xlsxlicense.xml"); //  license.xml应放在..WebRootWEB-INFclasses路径下
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static void excel2pdf(ByteArrayInputStream inputStream, ServletOutputStream responseOutputStream) {
        if (!getLicense()) {          // 验证License 若不验证则转化出的pdf文档会有水印产生
            return;
        }
        try {
            Workbook wb = new Workbook(inputStream);// 原始excel路径
            wb.save(responseOutputStream, SaveFormat.PDF);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
以下是 xlsxlicense.xml
<License>
  <Data>
    <Products>
      <Product>Aspose.Total for Java</Product>
      <Product>Aspose.Words for Java</Product>
    </Products>
    <EditionType>Enterprise</EditionType>
    <SubscriptionExpiry>20991231</SubscriptionExpiry>
    <LicenseExpiry>20991231</LicenseExpiry>
    <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
  </Data>
  <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>

其实整体看下来,无非是导数据到excel,然后转pdf。愣是折腾了好几天。。

反思了一下。 1.遇到有坑的框架,没有及时放弃。白白浪费了好多时间。
                        2.对各种框架,工具的使用不够熟练。

                        3.碰到难题,不够沉着冷静。过于浮躁。

                        4.菜是原罪!!!!!

posted @ 2022-10-26 01:59  小羊小恩  阅读(997)  评论(1编辑  收藏  举报