二十瞬 发表于 2022-11-21 22:28

excel转pdf 方案 java处理

本帖最后由 二十瞬 于 2022-11-21 22:35 编辑

最近项目需要用表单渲染,同时后面要涉及到pdf签章。研究了一下各个实现方案。

最终采用 excel使用 阿里的easyexcel 模板渲染成xlsx.   然后采用aspose的免费版生成pdf并移除水印,aspose的这个效果非常好 。
其余open office的列多一点的表格可能列就换行了。e-iceblue那个太抠了。只能转前3页。
代码大多都是从网上借鉴整合的。


模板如下


aspose生成pdf并移除水印

<repositories>
    <repository>
      <id>AsposeJavaAPI</id>
      <name>Aspose Java API</name>
      <url>https://releases.aspose.com/java/repo/</url>
    </repository>
</repositories>
<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-cells</artifactId>
    <version>22.11</version>
</dependency>

生成带水印的pdf
public static void aposePdf() throws Exception {
    Workbook workbook = new Workbook("d://aaaa.xlsx");
    workbook.save("Output.pdf");
}
移除水印

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.10</version>
</dependency>

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>

使用
Workbook workbook = new Workbook("d://aaaa.xlsx");
workbook.save("the.pdf");
replaceStr("the.pdf","Output1.pdf","Evaluation Only. Created with Aspose.Cells for Java.Copyright 2003 - 2022 Aspose Pty Ltd.");



/**
* 替换指定文字为白色的遮罩层
* @param src 需要被转换的带全路径文件名
* @param dest 转换之后pdf的带全路径文件名
* @param replaceStr 指定转换的文字(水印的文字)
*/
public static void replaceStr(String src, String dest, String replaceStr) {
    try {
      List<String> resu = new ArrayList<>();
      PdfReader reader = new PdfReader(src);
      //获取指定文字的坐标(就是上一步生成的pdf水印)
      getKeyWords(reader,replaceStr,resu);
      PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
      for (int i = 1; i <= resu.size(); i++) {
            String xy = resu.get(i - 1);
            PdfContentByte canvas = stamper.getOverContent(i);
            canvas.saveState();
            //设置颜色
            canvas.setColorFill(BaseColor.WHITE);
            //解析坐标
            double x = Double.valueOf(xy.split("--"));
            double y = Double.valueOf(xy.split("--")) - 10;
            //后面2个参数分别是宽高
            canvas.rectangle(x, y, 450, 100);
            canvas.fill();
            canvas.restoreState();
      }
      stamper.close();
      reader.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
}

/**
* 获取指定文字的坐标
*/
public static void getKeyWords(PdfReader pdfReader, String replaceStr,List<String> resu ) {
    try {
      int pageNum = pdfReader.getNumberOfPages();
      PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(
                pdfReader);
      for (int i = 1; i <= pageNum; i++) {
            pdfReaderContentParser.processContent(i, new RenderListener() {
                @Override
                public void renderText(TextRenderInfo textRenderInfo) {
                  String text = textRenderInfo.getText(); // 整页内容
                  if (null != text && text.contains(replaceStr)) {
                        Rectangle2D.Float boundingRectange = textRenderInfo
                              .getBaseline().getBoundingRectange();
                        String xy = boundingRectange.x + "--" + boundingRectange.y;
                        resu.add(xy);
                  }
                }
                @Override
                public void renderImage(ImageRenderInfo arg0) {
                }
                @Override
                public void endTextBlock() {
                }
                @Override
                public void beginTextBlock() {
                }
            });
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
}


要是在前端直接想以网页方式展现出来。 不使用插件pdf.js的话。 可以采用poi 的xls 转html。不过不支持xlsx格式


使用POI把Word Excel转为HTML
1:PoiUtil.java

package com.wzh.poi;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.poi.hssf.converter.ExcelToHtmlConverter;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.w3c.dom.Document;

/**@date 2015-3-16 17:22:05
* @author y
* @desc
*/
*
public class PoiUtil {

    /**@param fileName
   * @param outputFile
   * @throws FileNotFoundException
   * @throws IOException
   * @throws ParserConfigurationException
   * @throws TransformerConfigurationException
   * @throws TransformerException
   */
   * Excel 转为 HTML
   *
    public static void excelToHtml(String fileName, String outputFile)
            throws FileNotFoundException, IOException, ParserConfigurationException,
                TransformerConfigurationException, TransformerException {
      InputStream is = new FileInputStream(fileName);

      HSSFWorkbook excelBook = new HSSFWorkbook(is);

      ExcelToHtmlConverter ethc = new ExcelToHtmlConverter(
                DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
      ethc.setOutputColumnHeaders(false);
      ethc.setOutputRowNumbers(false);

      ethc.processWorkbook(excelBook);

      Document htmlDocument = ethc.getDocument();
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      DOMSource domSource = new DOMSource(htmlDocument);
      StreamResult streamResult = new StreamResult(out);
      
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer serializer = tf.newTransformer();
      serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
      serializer.setOutputProperty(OutputKeys.INDENT, "yes");
      serializer.setOutputProperty(OutputKeys.METHOD, "html");
      serializer.transform(domSource, streamResult);
      out.close();
      
      String htmlStr = new String(out.toByteArray());
      
      htmlStr = htmlStr.replace("<h2>Sheet1</h2>", "")
                         .replace("<h2>Sheet2</h2>", "")
                         .replace("<h2>Sheet3</h2>", "")
                         .replace("<h2>Sheet4</h2>", "")
                         .replace("<h2>Sheet5</h2>", "");
      
      writeFile(htmlStr, outputFile);
    }

    /**@param fileName
   * @param outputFile
   * @throws IOException
   * @throws ParserConfigurationException
   * @throws TransformerException
   */
   * Word 转为 HTML
   *
   *
    public static void wordToHtml(String fileName, String outputFile) throws
            IOException, ParserConfigurationException, TransformerException {
      HWPFDocument wordDoc = new HWPFDocument(new FileInputStream(fileName));

      WordToHtmlConverter wthc = new WordToHtmlConverter(
                DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());

      wthc.setPicturesManager(new PicturesManager() {

            @Override
            public String savePicture(byte[] bytes, PictureType pt, String string, float f, float f1) {
                return string;
            }

      });

      wthc.processDocument(wordDoc);

      List<Picture> pics = wordDoc.getPicturesTable().getAllPictures();
      if (null != pics && pics.size() > 0) {
            for (Picture pic : pics) {
                pic.writeImageContent(new FileOutputStream(pic.suggestFullFileName()));
            }
      }

      Document htmlDocument = wthc.getDocument();
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      DOMSource domSource = new DOMSource(htmlDocument);
      StreamResult streamResult = new StreamResult(out);

      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer serializer = tf.newTransformer();
      serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
      serializer.setOutputProperty(OutputKeys.INDENT, "yes");
      serializer.setOutputProperty(OutputKeys.METHOD, "html");
      serializer.transform(domSource, streamResult);

      out.close();

      String htmlStr = new String(out.toByteArray());
      writeFile(htmlStr, outputFile);
    }

    public static void writeFile(String content, String path) {
      FileOutputStream fos = null;
      BufferedWriter bw = null;

      File file = new File(path);

      try {
            fos = new FileOutputStream(file);

            bw = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
            bw.write(content);
      } catch (FileNotFoundException ex) {
            Logger.getLogger(PoiUtil.class.getName()).log(Level.SEVERE, null, ex);
      } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(PoiUtil.class.getName()).log(Level.SEVERE, null, ex);
      } catch (IOException ex) {
            Logger.getLogger(PoiUtil.class.getName()).log(Level.SEVERE, null, ex);
      } finally {
            try {
                if (null != bw) {
                  bw.close();
                }
                if (null != fos) {
                  fos.close();
                }
            } catch (IOException ex) {
                Logger.getLogger(PoiUtil.class.getName()).log(Level.SEVERE, null, ex);
            }

      }
    }
}

2.Test.java
import com.wzh.poi.PoiUtil;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;




/**@author y
*/
*
*
public class Test {

    /**@param args the command line arguments
   */
   *
    public static void main(String[] args) {
      try {
            PoiUtil.excelToHtml("t2.xls", "test.html");
      } catch (IOException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
      } catch (ParserConfigurationException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
      } catch (TransformerException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
      }
      
    }
   
}

另外也可以直接使用生产的html转pdf.但是效果和格式没有aspose的那么好



html 转pdf


<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>html2pdf</artifactId>
    <version>4.0.4</version>
</dependency>


    public static void htmlToPdf(String htmlStr, OutputStream outputStream){      ConverterProperties converterProperties = new ConverterProperties();      FontProvider fontProvider= new FontProvider();      fontProvider.addDirectory("C:\\Windows\\Fonts");      fontProvider.addStandardPdfFonts();      fontProvider.addSystemFonts(); //for fallback      converterProperties.setFontProvider(fontProvider);      HtmlConverter.convertToPdf(htmlStr, outputStream, converterProperties);    }



myxiaowang 发表于 2022-11-22 10:17

本帖最后由 myxiaowang 于 2022-11-22 10:26 编辑

看看我的
http://119.3.238.152:9001/mybucket/2022-11-22FBJNSGr4lXT1wcfNNq92R.png

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.apache.logging.log4j.util.Strings;
import org.xxx.xxx.base.pojo.PdfData;
import org.xxx.xxx.base.pojo.PdfInfo;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Objects;

/**
* @AuThor coderW
* @version 1.0.0
* @Description
* @createTime 2022年11月14日 15:44:00
*/
public class PdfUtil {


    /**
   *    todo demo
   * 创建一个pdf文档的样例
   * @Param outPath 输出路径
   * @param content 内容集合
   * @param titPath 字体
   * @param pdfInfo pdf属性
   * @throws IOException io
   */
    public static void createPdf(String outPath, ArrayList<PdfData> content, String titPath, PdfInfo pdfInfo) throws IOException {
      Document document = standA4Document();
      try (OutputStream outputStream = Files.newOutputStream(Paths.get(outPath))) {
            // 加载文档流
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            // 判断文档是否需要属性
            if(Objects.nonNull(pdfInfo)){
                setBaseInfo(document, pdfInfo.getAuthor(), pdfInfo.getKeywords(), pdfInfo.getProduct(), pdfInfo.getLink(), pdfInfo.getTitle(), pdfInfo.getSubject());
            }
            // 打开文档
            document.open();
            // 创建字体
            Font font = createFont(titPath);
            createFontStyle(font, 12f,null);
            // 创建表这里的数据模拟 从excel读取出来的数据
            ArrayList<Object> header = new ArrayList<>();
            header.add(" ");
            header.add("月总辐射量(kWh/m2)");
            header.add("月散射辐射(kWh/m2)");
            header.add("月直射辐射(kWh/m2)");
            header.add("平均气温(℃)");
            ArrayList<ArrayList<Object>> tableBody = new ArrayList<>();
            for (int i = 1; i <= 12; i++) {
                ArrayList<Object> d1 = new ArrayList<>();
                d1.add(i+"月");
                d1.add(RandomUtil.randomDouble());
                d1.add(RandomUtil.randomDouble());
                d1.add(RandomUtil.randomDouble());
                d1.add(RandomUtil.randomDouble());
                tableBody.add(d1);
            }
            createTable(document,header,tableBody,font,getBaseColor(244,244,244),new float[]{50,150,150,150,110},PageSize.A4,30,30);
            // 关闭文档
            document.close();
            // 关闭流
            writer.close();
      } catch (DocumentException e) {
            e.printStackTrace();
      }
    }






    /**
   * 创建一个表格
   * @param header 表头数据
   * @param body 表数据
   * @param font 字体
   * @param headerBaseColor 表头背景颜色 可以为空
   * @param colWidth 列宽度
   * @param pageSize 表适配大小
   * @param headerCellHeight 表头行高
   * @param bodyCellHeight 表数据行高
   * @throws DocumentException do
   */
    public static void createTable(Document document,ArrayList<Object> header,
                                 ArrayList<ArrayList<Object>> body,Font font,
                                 BaseColor headerBaseColor,
                                 float[] colWidth,
                                 Rectangle pageSize,
                                 float headerCellHeight,
                                 float bodyCellHeight
    ) throws DocumentException {
      PdfPTable pdfPTable = pdfPtable(header.size());
      pdfPTable.setHorizontalAlignment(Element.ALIGN_CENTER);
      if(colWidth != null){
            pdfPTable.setWidthPercentage(colWidth,pageSize);
      }
      // 创建表头
            if(CollectionUtil.isNotEmpty(header)){
            createTableData(pdfPTable,header,font,headerBaseColor,headerCellHeight);
      }
      // 填充数据
      if(CollectionUtil.isNotEmpty(body)){
            for (ArrayList<Object> list : body) {
                if(CollectionUtil.isNotEmpty(list)){
                  createTableData(pdfPTable,list,font,null,bodyCellHeight);
                }
            }
      }
      document.add(pdfPTable);
    }


    /**
   * 添加表头
   * @param table 表
   * @param data 单元格数据
   * @param font 字体
   * @param cellHeight 行高
   * @param baseColor 表头的背景颜色 如果不是表头可以不填写
   */
    public static void createTableData(PdfPTable table,ArrayList<Object> data,Font font,BaseColor baseColor,float cellHeight) {
      int numberOfColumns = table.getNumberOfColumns();
      for (int i = 0; i < numberOfColumns; i++){
            // 添加一个单元格
            PdfPCell cell = new PdfPCell();
            Paragraph elements = new Paragraph(data.get(i).toString(), font);
            cell.addElement(elements);
            // 设置行高
            cell.setLeading(3,3);
            // 设置字体居中
            cell.setPaddingLeft(10);
            cell.setFixedHeight(cellHeight);
            cell.setVerticalAlignment(Element.ALIGN_CENTER);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            // 设置背景边框
            if(baseColor != null){
                cell.setBackgroundColor(baseColor);
            }
            table.addCell(cell);
      }
    }



    /**
   * 创建一个表格
   * @param columns 列数
   * @Return PdfPTable
   */
    public static PdfPTable pdfPtable(int columns){
      return new PdfPTable(columns);
    }


    /**
   * 普通文本创建段落
   * @param document pdf
   * @param data 需要填充的文本
   * @param font 字体
   * @throws DocumentException do
   */
    public static void fillText(Document document,String data,Font font) throws DocumentException {
      Paragraph paragraph = createParagraph(font, data);
      document.add(paragraph);
    }

    /**
   * 基于对象的填充段落
   * @param document 文档
   * @param info 数据
   * @param titPath 字体路径
   * @param font 字体
   * @throws DocumentException do
   * @throws IOException io
   */
    public static void fillText(Document document,PdfData info,String titPath,Font font) throws DocumentException, IOException {
      if(Strings.isNotBlank(info.getTitle())){
            Font titledFont = createTitledFont(titPath, 18f, Font.BOLD);
            Paragraph p1 =createParagraph(titledFont,info.getTitle());
            p1.setAlignment(Element.ALIGN_LEFT);
            document.add(p1);
      }
      fillText(document,info.getData(),font);
    }

    /**
   * 添加一张图片
   * @param image 图片对象
   * @param document 文档
   * @throws DocumentException do
   */
    public static void addImage(Image image, Document document) throws DocumentException {
      setImage(image,100,60);
      document.add(image);

    }



    /**
   * 支持像素缩放 查看Image对象
   * 按百分比缩放图片 对称缩放
   * @param image 图片对象
   * @param scalePercent 百分比
   */
    public static void setImage(Image image,float scalePercent){
      image.scalePercent(scalePercent);
      image.setAlignment(Image.MIDDLE);
    }

    /**
   * 百分比缩放
   * @param image 图片对象
   * @param scalePercentX 长缩放
   * @param scalePercentY 宽缩放
   */
    public static void setImage(Image image,float scalePercentX,float scalePercentY){
      image.scalePercent(scalePercentX,scalePercentY);
      image.setAlignment(Image.MIDDLE);
    }


    /**
   * 创建一张图片
   * @param path 路径
   * @return Image
   * @throws BadElementException ex
   * @throws IOException io
   */
    public static Image getImage(String path) throws BadElementException, IOException {
      return Image.getInstance(path);
    }




    /**
   * 写出数据
   * @param content 数据
   */
    public static void fillText( PdfContentByte content){
      content.fill();
      content.sanityCheck();
    }


    /**
   * 创建字体
   * @return Font
   */
    public static Font createFont(){
      return new Font();
    }


    /**
   * 给字体设置样式
   * @param font 字体
   * @param fontSize 字体大小
   * @param baseColor 字体颜色
   * @param style 样式 Font.BOLD 等方法
   */
    public static void createFontStyle(Font font,Float fontSize,BaseColor baseColor,Integer... style){
      if(Objects.isNull(font)){
            return;
      }
      font.setSize(fontSize);
      if(baseColor != null){
            font.setColor(baseColor);
      }
      if(style != null){
            for (Integer integer : style) {
                font.setStyle(integer);
            }
      }

    }

    /**
   * 创建字体颜色
   * @param red 红
   * @param green 绿
   * @param blue 蓝
   * @return BaseColor
   */
    public static BaseColor getBaseColor(Integer red,Integer green,Integer blue){
      return new BaseColor(red,green,blue);
    }

    /**
   * 创建指定字体的font
   * @param fontPath font路径
   * @return Font
   * @throws DocumentException 文档异常
   * @throws IOException io异常
   */
    public static Font createFont(String fontPath) throws DocumentException, IOException {
      BaseFont font = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
      return new Font(font);
    }

    /**
   * 添加标题大小的字体
   * @param fontPath 字体路径
   * @param size 大小
   * @param style 样式
   * @return Font
   * @throws DocumentException dx
   * @throws IOException io
   *
   * tip: createTitleFont(path,22,Font.BOLD)
   */
    public static Font createTitledFont(String fontPath,float size,int style) throws DocumentException, IOException {
      BaseFont font = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
      return new Font(font, size, style);
    }

    /**
   * 创建一个段落
   * @param font 字体
   * @param content 内容
   * @return Paragraph
   * @throws DocumentException 文档异常
   */
    public static Paragraph createParagraph(Font font,String content) throws DocumentException {
      Paragraph elements = new Paragraph(content, font);
      // 设置首行缩进
      elements.setFirstLineIndent(20f);
      return elements;
    }

    /**
   * 创建一个指定大小宽度的页面
   * @param width 宽度
   * @param height 高度
   * @return Rectangle
   */
    public static Rectangle createRectangle(Integer width,Integer height){
      return new Rectangle(width,height);
    }


    /**
   * 创建一个pdf
   * @param pageSize pdf页大小对象
   * @param marginLeft 距离左边边距
   * @param marginRight 距离右边边距
   * @param marginTop 距离上边边距
   * @param marginBottom 距离下边边距
   * @return Document
   */
    public static Document createDocument(Rectangle pageSize,int marginLeft,int marginRight,int marginTop,int marginBottom){
      return new Document(pageSize,marginLeft,marginRight,marginTop,marginBottom);
    }
    /**
   * 创建一个标准的pdf
   * // todo PageSize 内置很多样式大小
   *
   * @return Document
   */
    public static Document standA4Document(){
      return new Document(PageSize.A4);
    }

    /**
   * pdf相关信息
   *
   * @param document pdf
   * @param author   作者
   * @param keywords 关键字
   * @param product产品
   * @param link   官网连接
   * @param title    标题
   * @param subject主题
   */
    public static void setBaseInfo(Document document, String author, String keywords, String product, String link, String title, String subject){
      document.addAuthor(author);
      document.addCreationDate();
      document.addKeywords(keywords);
      Meta producer = new Meta("producer", product);
      try {
            document.add(producer);
      } catch (DocumentException e) {
            throw new RuntimeException(e);
      }
      document.addCreator(link);
      document.addTitle(title);
      document.addSubject(subject);
    }


}



其他代码没用贴完 但是做个java都能看出来

二十瞬 发表于 2022-11-22 16:09

iawyxkdn8 发表于 2022-11-22 08:09
你干的活,跟我怎么差不多,一堆的文件+一 堆的章

前段时间接手公司电子证照产品   那才是麻烦。 三十多个证照的模板那个模板还是 word 编写。转xml   去里面写freemaker 标签。 然后渲染出doc再转pdf.....

newtin 发表于 2022-11-22 00:10

在任何地方,都有人在创新。{:1_921:}

penz 发表于 2022-11-22 00:29

学习了,楼主厉害

Laotu 发表于 2022-11-22 00:42

已收藏,慢慢学习

pj686pp 发表于 2022-11-22 01:00

慢慢学习,感谢分享

zzk19358590281 发表于 2022-11-22 07:46

lou zhu wei wu

King1993 发表于 2022-11-22 08:00

正好在学习这个,收藏了

tieluxiaoyou 发表于 2022-11-22 08:04

下次一定用,留着有用

l441669899 发表于 2022-11-22 08:04

学习学习,感谢楼主分享!

iawyxkdn8 发表于 2022-11-22 08:09

你干的活,跟我怎么差不多,一堆的文件+一 堆的章
页: [1] 2 3 4
查看完整版本: excel转pdf 方案 java处理