package com.yeejoin.amos.file.convert;

import org.apache.pdfbox.multipdf.Splitter;
import org.apache.pdfbox.pdmodel.PDDocument;

import javax.servlet.http.HttpServletResponse;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import com.aspose.words.*;
import com.spire.pdf.FileFormat;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.widget.PdfPageCollection;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import com.aspose.pdf.SvgLoadOptions;
import com.aspose.cells.PdfSaveOptions;
import com.aspose.cells.Workbook;

@Slf4j
public class PDFConvert {
    // 涉及到的路径
    // 1、pdf所在的路径，真实测试种是从外部引入的

    /**
     * 2、如果是大文件，需要进行切分，保存的子pdf路径
     */
    static String splitPath = "./split/";

    /**
     * 3、如果是大文件，需要对子pdf文件一个一个进行转化
     */
    static String docPath = "./doc/";
    
	/**
     * 将word文档转为PDF文档
     *
     * @param inputPath word文档所在的地址
     * @param outPath 生成pdf输出的地址
     * @param fileName 生成后PDF的名字<b>注意：名字不要带后缀，下面自动封装了。</b>
     * @throws Exception
     */
    private static void word2pdf(String inputPath, String outPath, String fileName) throws Exception {
        Document doc = new Document(inputPath);
        // 获取控制修订外观的RevisionOptions对象
        RevisionOptions revisionOptions = doc.getLayoutOptions().getRevisionOptions();
        // 在引出序号中显示删除修订
        revisionOptions.setShowInBalloons(ShowInBalloons.FORMAT_AND_DELETE);
        // 输出
        doc.save(outPath + "\\" + fileName+ ".pdf");
    }
    
    
    /**
     * 将word文档转为PDF文档
     *
     * @param inputPath word文档所在的地址
     * @param outPath 生成pdf输出的地址
     * @param fileName 生成后PDF的名字<b>注意：名字不要带后缀，下面自动封装了。</b>
     * @throws Exception
     */
    private static void word2pdf(String inputPath, OutputStream out, String fileName) throws Exception {
        Document doc = new Document(inputPath);
        // 获取控制修订外观的RevisionOptions对象
        RevisionOptions revisionOptions = doc.getLayoutOptions().getRevisionOptions();
        // 在引出序号中显示删除修订
        revisionOptions.setShowInBalloons(ShowInBalloons.FORMAT_AND_DELETE);
        doc.save(out, 1);
    }
    
    /**
     * 将SVG转为PDF
     * @param inputPath svg所在的地址
     * @param outPath 生成pdf输出的地址
     */
    public static void svg2pdf(String inputPath, String outPath){
        // Instantiate LoadOption object using SVG load option
    	com.aspose.pdf.LoadOptions options = new SvgLoadOptions();
        // Create Document object
    	com.aspose.pdf.Document document = new com.aspose.pdf.Document(inputPath, options);
        document.save(outPath);
    }
    
    /**
     * 将SVG转为PDF
     * @param inputPath svg所在的地址
     * @param outPath 生成pdf输出的地址
     */
    public static void svg2pdf(String inputPath, OutputStream out){
        // Instantiate LoadOption object using SVG load option
    	com.aspose.pdf.LoadOptions options = new SvgLoadOptions();
        // Create Document object
    	com.aspose.pdf.Document document = new com.aspose.pdf.Document(inputPath, options);
        document.save(out);
    }
    
    /**
    *
    * @param fileName 文件名称
    * @param pageNum 读取的页数
    * @param filePath 文件路径
    * @return
    */
   public void splitPdf(HttpServletResponse response, int pageNum, String filePath) {
       // 这是对应文件名
       File indexFile = new File(filePath);
       PDDocument document = null;
       try {
           document = PDDocument.load(indexFile);
           // 获取总页数
           int numberOfPages = document.getNumberOfPages();
           System.out.println("总页数告诉你哦："+numberOfPages);

           Splitter splitter = new Splitter();
           // 开始页
           splitter.setStartPage(pageNum);
           // 结束页
           splitter.setEndPage(pageNum);
           List<PDDocument> pages = splitter.split(document);
           for (PDDocument pdDocument : pages){
               pdDocument.save(response.getOutputStream());
               pdDocument.close();
           }
           document.close();
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
   

   /**
    * `excel` 转 `pdf`
    *
    * @param excelBytes: html字节码
    * @return 生成的`pdf`文件流
    * @author zhengqing
    * @date 2020/11/24 11:26
    */
   @SneakyThrows(Exception.class)
   public static byte[] excelBytes2PdfBytes(byte[] excelBytes) {
       Workbook workbook = new Workbook(new ByteArrayInputStream(excelBytes));
       // 设置pdf保存的格式以及强制所有列都在同一页
       PdfSaveOptions pso = new PdfSaveOptions();
       pso.setAllColumnsInOnePagePerSheet(true);
       ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
       workbook.save(outputStream, pso);
       // workbook.save(outputStream, SaveFormat.PDF);
       // 返回生成的`pdf`文件字节码
       return outputStream.toByteArray();
   }

   /**
    * `excel` 转 `pdf`
    *
    * @param excelBytes:  html字节码
    * @param pdfFilePath: 待生成的`pdf`文件路径
    * @return 生成的`pdf`文件数据
    * @author zhengqing
    * @date 2020/11/24 11:26
    */
   @SneakyThrows(Exception.class)
   public static File excelBytes2PdfFile(byte[] excelBytes, String pdfFilePath) {
       Workbook workbook = new Workbook(new ByteArrayInputStream(excelBytes));
       // 设置pdf保存的格式以及强制所有列都在同一页
       PdfSaveOptions pso = new PdfSaveOptions();
       pso.setAllColumnsInOnePagePerSheet(true);
       workbook.save(pdfFilePath, pso);
       // workbook.save(outputStream, SaveFormat.PDF);
       return new File(pdfFilePath);
   }

   

	/**
	 * 
	 * @param srcPath
	 * @param desPath
	 */
   public static void pdf2Word(String srcPath, String desPath) {
       // 4、desPath:最终生成的doc所在的目录，默认是和引入的一个地方，开源时对外提供下载的接口。
       boolean result = false;
       try {
           // 0、判断输入的是否是pdf文件
           // 第一步：判断输入的是否合法
           boolean flag = isPDFFile(srcPath);
           // 第二步：在输入的路径下新建文件夹
           boolean flag1 = create();

           if (flag && flag1) {
               // 1、加载pdf
               PdfDocument pdf = new PdfDocument();
               pdf.loadFromFile(srcPath);
               PdfPageCollection num = pdf.getPages();

               // 2、如果pdf的页数小于11，那么直接进行转化
               if (num.getCount() <= 10) {
                   pdf.saveToFile(desPath, com.spire.pdf.FileFormat.DOCX);
               }
               // 3、否则输入的页数比较多，就开始进行切分再转化
               else {
                   // 第一步：将其进行切分,每页一张pdf
                   pdf.split(splitPath + "test{0}.pdf", 0);

                   // 第二步：将切分的pdf，一个一个进行转换
                   File[] fs = getSplitFiles(splitPath);
                   for (File f : fs) {
                       PdfDocument sonpdf = new PdfDocument();
                       sonpdf.loadFromFile(f.getAbsolutePath());
                       sonpdf.saveToFile(docPath + f.getName().substring(0, f.getName().length() - 4) + ".docx",
                           FileFormat.DOCX);
                   }
                   // 第三步：对转化的doc文档进行合并，合并成一个大的word
                   try {
                       result = merge(docPath, desPath);
                       log.debug(String.valueOf(result));
                   } catch (Exception e) {
                       e.printStackTrace();
                   }

               }
           } else {
               log.debug("输入的不是pdf文件");
           }
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           // 4、把刚刚缓存的split和doc删除
           if (result) {
               clearFiles(splitPath);
               clearFiles(docPath);
           }
       }
       log.debug("转换成功");
   }

   private static boolean create() {
       File f = new File(splitPath);
       File f1 = new File(docPath);
       if (!f.exists()) {
           f.mkdirs();
       }
       if (!f.exists()) {
           f1.mkdirs();
       }
       return true;
   }

   /**
    * 判断是否是pdf文件
    */
   private static boolean isPDFFile(String srcPath2) {
       File file = new File(srcPath2);
       String filename = file.getName();
       if (filename.endsWith(".pdf")) {
           return true;
       }
       return false;
   }

   /**
    * 取得某一路径下所有的pdf
    */
   private static File[] getSplitFiles(String path) {
       File f = new File(path);
       File[] fs = f.listFiles();
       if (fs == null) {
           return null;
       }
       return fs;
   }

   public static void clearFiles(String workspaceRootPath) {
       File file = new File(workspaceRootPath);
       if (file.exists()) {
           deleteFile(file);
       }
   }

   public static void deleteFile(File file) {
       if (file.isDirectory()) {
           File[] files = file.listFiles();
           for (int i = 0; i < files.length; i++) {
               deleteFile(files[i]);
           }
       }
       file.delete();
   }

   private static boolean merge(String docPath, String desPath) {
       File[] fs = getSplitFileList(docPath);
       System.out.println(docPath);
       com.spire.doc.Document document = new com.spire.doc.Document(docPath + "test0.docx");

       for (int i = 1; i < fs.length; i++) {
           document.insertTextFromFile(docPath + "test" + i + ".docx", com.spire.doc.FileFormat.Docx_2013);
       }
       // 第四步：对合并的doc进行保存2
       document.saveToFile(desPath);
       return true;
   }

   /**
    * 取得某一路径下所有的pdf
    */
   private static File[] getSplitFileList(String path) {
       File f = new File(path);
       return f.listFiles();
   }
}
