package com.tykj.dev.device.file.util;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import com.tykj.dev.device.file.entity.*;
import com.tykj.dev.device.zxing.util.ZXingUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ResourceUtils;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName html.java
 * @Description TODO
 * @createTime 2021年01月23日 15:04:00
 */
@Slf4j
public class JavaToPdfHtmlFreeMarker {
    @Value("${file.path}")
    public String url;

    @Value("${preview.path}")
    public String preview;
    private static final Map<Integer,String> MAP= new HashMap<Integer, String>() {
        {
            put(1,"第一联发机单位存");
            put(2,"第二联收机单位存");
            put(3,"第三联退发机单位存");

        }
    };

    private static final Map<Integer,String> MAP1= new HashMap<Integer, String>() {
        {
            put(1,"第一联上级1单位存");
            put(2,"第二联上级2单位存");
            put(3,"第三联本级单位存");

        }
    };
    private static final String DEST = "/Users/zjm/code/Template/HelloWorld_CN_HTML_FREEMARKER.pdf";
    private static final String HTML = "bill.html";//template_freemarker
    private static final String FONT = "/Users/zjm/code/Template/simhei.ttf";

    private static Configuration freemarkerCfg = null;

    static {
        freemarkerCfg =new Configuration();
        //freemarker的模板目录
        try {
            freemarkerCfg.setDirectoryForTemplateLoading(new File(ResourceUtils.getURL("classpath:").getPath()+"htmlTemplate/"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws IOException, DocumentException {
        Documents documents=new Documents();
        documents.setNumber("NO:第221321134号");
        documents.setReceiveUnit("杭州机要");
        documents.setReplyNum("123123123131");
        documents.setSenderUnit("浙江省");
        documents.setTitle("密码装备清退单");
        List<DocumentDevice> documentDevices=new ArrayList<>();
        for (int i=0;i<20;i++){
            DocumentDevice documentDevice=new DocumentDevice();
            documentDevice.setCount(i);
            documentDevice.setModel("MM001");
            documentDevice.setRemark("备注");
            documentDevice.setApplicationField("省一级");
            documentDevice.setDeviceSerialNumber("asdq1231232");
            documentDevice.setProductionSerialNumber("12312312312");
            documentDevice.setParts("密码机");
            documentDevice.setCategory("装备");
            documentDevice.setSecurityClassification("机密");
            documentDevices.add(documentDevice);
        }
        documents.setDocumentDevices(documentDevices);
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRender(documents,"/Users/zjm/code/test-tu/htmlModel/");
        JavaToPdfHtmlFreeMarker.createPdf(content,"/Users/zjm/code/test-tu/","12313","documents/");
    }




    public static FileRet createPdf(String[] htmlFiles,String path,String preview,String folderName){

        Long startTime = System.currentTimeMillis();
        Document document = new Document();

        String name=UUID.randomUUID().toString()+".pdf";
        String pdfPath=path+folderName+name;
        PdfCopy pdfCopy = null; //创建一个新文件
        try {
            pdfCopy = new PdfCopy(document, new FileOutputStream(pdfPath));
            document.open();
            for (String htmlFile : htmlFiles) {
                if (htmlFile != null) {
                    String url = new File(htmlFile).toURI().toURL().toString();
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    ITextRenderer renderer = new ITextRenderer();
                    renderer.setDocument(htmlFile);
                    // 解决中文不显示问题
                    ITextFontResolver fontResolver = renderer.getFontResolver();
                    fontResolver.addFont(ResourceUtils.getURL("classpath:").getPath()+"font/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                    fontResolver.addFont(ResourceUtils.getURL("classpath:").getPath()+"font/simhei2.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                    renderer.layout();
                    renderer.createPDF(os);
                    PdfReader pdfReader = new PdfReader(os.toByteArray());
                    PdfDictionary pdfDictionary= pdfReader.getPageN(1);
                    pdfDictionary.put(PdfName.ROTATE, new PdfNumber(90));
                    for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
                        PdfImportedPage importedPage = pdfCopy.getImportedPage(pdfReader, i);
                        pdfCopy.addPage(importedPage);
                    }
                    os.close();
                }
            }
                Long endTime = System.currentTimeMillis();
                System.out.print("Itext parse Html to Pdf End -> " + (endTime - startTime));
            return new FileRet(name, pdfPath, preview +folderName+ name);
        } catch (IOException | com.lowagie.text.DocumentException | DocumentException e) {
            log.error("[PDf] 生成pdf未找到地址：{}",pdfPath);
        } finally {
            document.close();
        }
            return  new FileRet();
    }

    public static FileRet createPdf90(String[] htmlFiles,String path,String preview,String folderName){

        Long startTime = System.currentTimeMillis();
        Document document = new Document();

        String name=UUID.randomUUID().toString()+".pdf";
        String pdfPath=path+folderName+name;
        PdfCopy pdfCopy = null; //创建一个新文件
        try {
            pdfCopy = new PdfCopy(document, new FileOutputStream(pdfPath));
            document.open();
            for (String htmlFile : htmlFiles) {
                if (htmlFile != null) {
                    String url = new File(htmlFile).toURI().toURL().toString();
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    ITextRenderer renderer = new ITextRenderer();
                    renderer.setDocument(htmlFile);
                    // 解决中文不显示问题
                    ITextFontResolver fontResolver = renderer.getFontResolver();
                    fontResolver.addFont(ResourceUtils.getURL("classpath:").getPath()+"font/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                    fontResolver.addFont(ResourceUtils.getURL("classpath:").getPath()+"font/simhei2.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                    renderer.layout();
                    renderer.createPDF(os);
                    PdfReader pdfReader = new PdfReader(os.toByteArray());
//                    PdfDictionary pdfDictionary= pdfReader.getPageN(1);
//                    pdfDictionary.put(PdfName.ROTATE, new PdfNumber(90));
                    for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
                        PdfImportedPage importedPage = pdfCopy.getImportedPage(pdfReader, i);
                        pdfCopy.addPage(importedPage);
                    }
                    os.close();
                }
            }
            Long endTime = System.currentTimeMillis();
            System.out.print("Itext parse Html to Pdf End -> " + (endTime - startTime));
            return new FileRet(name, pdfPath, preview +folderName+ name);
        } catch (Exception e) {
            log.error("[PDf] 生成pdf未找到地址：{}",pdfPath);
//            e.printStackTrace();
        } finally {
            document.close();
        }
        return  new FileRet();
    }



    /**
     * freemarker渲染html
     */
    public static String[] freeMarkerRender(Documents documents,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;

        try {
            String QRCode= ZXingUtil.encode(documents.getId());
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate("bill.html");
            template.setEncoding("UTF-8");

            List<DocumentDevice> list=documents.getDocumentDevices();
            List<List<DocumentDevice>> listList=toDocList(list);
            int count=listList.size();
            for (int i=1; i<=3; i++){
                Integer page=1;
                for (List<DocumentDevice> list1:listList) {
                    String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                    // 合并数据模型与模板
                    FileWriter fileWriter = new FileWriter(new File(htmlname));
                    template.process(toMap(documents,list1,MAP.get(i),page,count,QRCode),fileWriter);
                    out.flush();
                    strings[index]=htmlname;
                    index++;
                    page++;
                }
            }
            return strings;
        } catch (Exception e) {
            log.error("[freeMarkerRender] 方法找不到地址：{}",htmlPath);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    /**
     * freemarker渲染html 维修业务单据 生成html页面。
     */
    public static String[] freeMarkerRenderRepair(Documents documents,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;

        try {
            String QRCode= ZXingUtil.encode(documents.getId());
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate("repair.html");
            template.setEncoding("UTF-8");

            List<DocumentDevice> list=documents.getDocumentDevices();
            List<List<DocumentDevice>> listList=toDocList(list);
            int count=listList.size();
            for (int i=1; i<=3; i++){
                Integer page=1;
                for (List<DocumentDevice> list1:listList) {
                    String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                    // 合并数据模型与模板
                    FileWriter fileWriter = new FileWriter(new File(htmlname));
                    template.process(toMap(documents,list1,MAP.get(i),page,count,QRCode),fileWriter);
                    out.flush();
                    strings[index]=htmlname;
                    index++;
                    page++;
                }
            }
            return strings;
        } catch (Exception e) {
            log.error("[freeMarkerRender] 方法找不到地址：{}",htmlPath);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    public static String[] freeMarkerRender1(Documents documents,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;
        try {
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate("bill.html");
            template.setEncoding("UTF-8");

            List<DocumentDevice> list=documents.getDocumentDevices();
            List<List<DocumentDevice>> listList=toDocList(list);
            int count=listList.size();
            for (int i=1; i<=3; i++){
                Integer page=1;
                for (List<DocumentDevice> list1:listList) {
                    String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                    // 合并数据模型与模板
                    FileWriter fileWriter = new FileWriter(new File(htmlname));
                    template.process(toMap(documents,list1,MAP.get(i),page,count),fileWriter);
                    out.flush();
                    strings[index]=htmlname;
                    index++;
                    page++;
                }
            }
            return strings;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    public static List<List<DocumentDevice>> toDocList(List<DocumentDevice> deviceList) throws UnsupportedEncodingException {
        List<List<DocumentDevice>> lists=new ArrayList<>();
        List<DocumentDevice> documentDevices=new ArrayList<>();
        int i=0;
        Integer code=0;
        for (int j=0;j< deviceList.size();j++){
            DocumentDevice documentDevice=deviceList.get(j);
            int  max= toMax2(documentDevice);
            if (i+max==14){
                String s=String.join("",toListString(documentDevice.getDeviceSerialNumber(),56));
                documentDevice.setOneCount(max);
                documentDevice.setModel(String.join("",toListString(documentDevice.getModel(),13)));
                documentDevice.setParts(String.join("",toListString(documentDevice.getParts(),13)));
                documentDevice.setRemark(String.join("",toListString(documentDevice.getRemark(),12)));
                documentDevice.setDeviceSerialNumber(s);
                code++;
                documentDevice.setCode(code);
                documentDevices.add(documentDevice);
                lists.add(documentDevices);
                documentDevices=new ArrayList<>();
                i=0;
            }else if (i+max>14){
                //当前页面少了多少行
                int differ=14-i;
                List<String> modelList= toListString(documentDevice.getModel(),13);
                List<String> seqList=toListString(documentDevice.getDeviceSerialNumber(),56);
                List<String> pasList=toListString(documentDevice.getParts(),13);
                List<String> remarkList=toListString(documentDevice.getRemark(),12);
                DocumentDevice documentDevice1=new DocumentDevice();
                if (modelList.size()>differ){
                    documentDevice.setModel(String.join("",modelList.subList(0,differ)));
                    documentDevice1.setModel(String.join("",modelList.subList(differ,modelList.size())));
                }else {
                    documentDevice.setModel(String.join("",modelList.subList(0,differ)));

                }
                if (seqList.size()>differ){
                    documentDevice.setDeviceSerialNumber(String.join("",seqList.subList(0,differ)));
                    documentDevice1.setDeviceSerialNumber(String.join("",seqList.subList(differ,seqList.size())));
                }else {
                    documentDevice.setDeviceSerialNumber(String.join("",seqList.subList(0,seqList.size())));

                }
                if (pasList.size()>differ){
                    documentDevice.setParts(String.join("",pasList.subList(0,differ)));
                    documentDevice1.setParts(String.join("",pasList.subList(differ,pasList.size())));
                }else {
                    documentDevice.setParts(String.join("",pasList.subList(0,pasList.size())));
                }
                if (remarkList.size()>differ){
                    documentDevice.setRemark(String.join("",remarkList.subList(0,differ)));
                    documentDevice1.setRemark(String.join("",remarkList.subList(differ,remarkList.size())));
                }else {
                    documentDevice.setRemark(String.join("",remarkList));
                }
                code++;
                documentDevice.setCode(code);
                documentDevice.setOneCount(differ);
                documentDevices.add(documentDevice);
                lists.add(documentDevices);
                documentDevices=new ArrayList<>();
                code++;
                documentDevice1.setCode(code);
                documentDevice1.setOneCount(max-differ);
                documentDevices.add(documentDevice1);
                i=max-differ;
            }else {
                String s=String.join("",toListString(documentDevice.getDeviceSerialNumber(),56));
                code++;
                documentDevice.setCode(code);
                documentDevice.setModel(String.join("",toListString(documentDevice.getModel(),13)));
                documentDevice.setParts(String.join("",toListString(documentDevice.getParts(),13)));
                documentDevice.setRemark(String.join("",toListString(documentDevice.getRemark(),12)));
                documentDevice.setOneCount(max);
                documentDevice.setDeviceSerialNumber(s);
                documentDevices.add(documentDevice);
                i=i+max;
            }
        }
        if (documentDevices.size()!=0){
            lists.add(documentDevices);
        }
        return lists;

    }


    private static int toMax2(DocumentDevice documentDevice){
        int partsCount=String_length(documentDevice.getParts());
        int deviceSerialNumberCount=String_length(documentDevice.getDeviceSerialNumber());
        int modelCount=String_length(documentDevice.getModel());
        int remarkCount=String_length(documentDevice.getRemark());
        int parts = (partsCount%13>0) ? partsCount/13 + 1 :  partsCount/13;
        int deviceSerialNumber=(deviceSerialNumberCount%56>0) ? deviceSerialNumberCount/56 + 1 :  deviceSerialNumberCount/56;
        int model=(modelCount%13>0) ? modelCount/13 + 1 :  modelCount/13;
        int remark=(remarkCount%12>0) ? remarkCount/12 + 1 :  remarkCount/12;
        int  max=parts;
        //求最大
        if(max<deviceSerialNumber){
            max=deviceSerialNumber;

        }
        if(max<model) {
            max = model;
        }
        if (max<remark){
            max=remark;
        }

        return max;
    }


    private static int toMaxList(List<String> strings){
        Integer count=strings.size();
        return (count%6>0) ? count/6 + 1 : count/6;
    }

    private static String seqToString(List<String> strings){
        StringBuilder stringBuilder=new StringBuilder();

        strings.forEach(
                s -> {
                    stringBuilder.append("  ").append(s).append("  ");
                }
        );
        stringBuilder.append("<br />");
        return stringBuilder.toString();
    }

    private static String toALLSeqStirng(List<String> strings){
        int count=toMaxList(strings);
        StringBuilder allStirng= new StringBuilder();
        for (int i=1;i<=count;i++){
            if (i*6<strings.size()) {
                allStirng.append(seqToString(strings.subList((i - 1) * 6, i * 6)));
            }else {
                allStirng.append(seqToString(strings.subList((i - 1) * 6, strings.size())));
            }
        }
        return allStirng.toString();
    }

    private static List<String> toListString(String str,int len) throws UnsupportedEncodingException {

        List<String> list =new ArrayList<>();
        if (str!=null && !str.equals("")) {
            int stringLen = String_length(str);
            int count = (stringLen % len > 0) ? stringLen / len + 1 : stringLen / len;
            if (stringLen > len) {
//            boolean falg=true;
//            int i=0;
//            while (falg){
//                if ((i+1)*len>stringLen) {
//                    list.add(subString(str,i*len+1,stringLen,"GBK"));
//                    falg=false;
//                }else {
//                    list.add(subString(str,i*len+1,(i+1)*len,"GBK")+"<br/>");
//                    i++;
//                }
//            }
                for (int i = 1; i <= count; i++) {
                    if (i * len < stringLen) {
                        list.add(subString(str, (i - 1) * len, i * len, "GBK") + "<br/>");
                    } else {
                        list.add(subString(str, (i - 1) * len, stringLen, "GBK") + "<br/>");

                    }
                }
                return list;
            } else {
                list.add(str);
                return list;
            }
        }else {
           return list;
        }

    }

    public static String subString(String text, int start, int end, String encode) throws UnsupportedEncodingException {
        if( text == null || text == "")
            return null;
        StringBuffer sb = new StringBuffer();
        int currentLength = 0;
        for( char c : text.toCharArray() )
        {
            currentLength += String_length(String.valueOf(c));
            if( currentLength > start && currentLength <= end )
            {
                sb.append(c);
            }else {
                continue;
            }
        }
        return sb.toString();
    }








    public static List<String> freeMarkerRenderList(Documents documents,String htmlPath) {
        Writer out = new StringWriter();
        List<String> listCont=new ArrayList<>();
        try {
            String QRCode= ZXingUtil.encode(documents.getId());
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate("bill.html");
            template.setEncoding("UTF-8");

            List<DocumentDevice> list=documents.getDocumentDevices();
            List<List<DocumentDevice>> listList=toDocList(list);
            int count=listList.size();
            for (int i=1; i<=3; i++){
                Integer page=1;
                for (List<DocumentDevice> list1:listList) {
                    String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                    // 合并数据模型与模板
                    FileWriter fileWriter = new FileWriter(new File(htmlname));
                    template.process(toMap(documents,list1,MAP.get(i),page,count,QRCode),fileWriter);
                    out.flush();
                    listCont.add(htmlname);
                    page++;
                }
            }
            return listCont;
        } catch (Exception e) {
            log.error("[freeMarkerRenderList] 方法找不到地址：{}",htmlPath);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    private static Map<String,Object> toMap(Documents documents,List<DocumentDevice> list,String test,Integer page,Integer count){
        Map<String,Object> data = new HashMap();

        data.put("ul",test);
        data.put("number",documents.getNumber());
        data.put("title",documents.getTitle());
        data.put("receiveUnit",documents.getReceiveUnit());
        data.put("replyNum",documents.getReplyNum());
        data.put("senderUnit",documents.getSenderUnit());
        data.put("page",page);
        data.put("count",count);
        if (documents.getSrcA()==null||documents.getSrcA().equals("")){
            data.put("srcA","\""+1+"\"");
        }else {
            data.put("srcA","\""+documents.getSrcA()+"\"");
        }
        data.put("nameA",documents.getNameA());
        data.put("nameA1",documents.getNameA1());
        data.put("nameB",documents.getNameB());
        data.put("nameB1",documents.getNameB1());

        if (documents.getSrcB()==null||documents.getSrcB().equals("")){
            data.put("srcB","\""+1+"\"");
        }else {
            data.put("srcB","\""+documents.getSrcB()+"\"");
        }
        List<DocumentDevice> list1=new ArrayList<>();
        AtomicInteger i= new AtomicInteger(1);
        list.forEach(
                documentDevice -> {
                    documentDevice.setCode(i.get());
                    i.set(i.get() + 1);
                    list1.add(documentDevice);
                }
        );
        data.put("documentDevices",list1);
        return data;
    }


    private static Map<String,Object> toMap(Documents documents,List<DocumentDevice> list,String test,Integer page,Integer count,String QRCode){
        Map<String,Object> data = new HashMap();

        data.put("ul",test);
        data.put("number",documents.getNumber());
        data.put("title",documents.getTitle());
        data.put("receiveUnit",documents.getReceiveUnit());
        data.put("replyNum",documents.getReplyNum());
        data.put("senderUnit",documents.getSenderUnit());
        data.put("page",page);
        data.put("count",count);
        data.put("QRCode","\""+"data:image/png;base64,"+QRCode+"\"");
        if (documents.getSrcA()==null||documents.getSrcA().equals("")){
            data.put("srcA","\""+1+"\"");
        }else {
            data.put("srcA","\""+documents.getSrcA()+"\"");
        }
        data.put("nameA",documents.getNameA());
        data.put("nameA1",documents.getNameA1());
        data.put("nameB",documents.getNameB());
        data.put("nameB1",documents.getNameB1());

        if (documents.getSrcB()==null||documents.getSrcB().equals("")){
            data.put("srcB","\""+1+"\"");
        }else {
            data.put("srcB","\""+documents.getSrcB()+"\"");
        }
//        List<DocumentDevice> list1=new ArrayList<>();
//        AtomicInteger i= new AtomicInteger(1);
//        list.forEach(
//                documentDevice -> {
//                    documentDevice.setCode(i.get());
//                    i.set(i.get() + 1);
//                    list1.add(documentDevice);
//                }
//        );
        data.put("documentDevices",list);
        return data;
    }




    private static Map<String,Object> toConfirmMap(Confirm confirm, List<DocumentDevice> list,Integer page,Integer count){
        Map<String,Object> data = new HashMap();
        data.put("title",confirm.getTitle());
        data.put("unit",confirm.getUnit());
        data.put("page",page);
        data.put("count",count);
        data.put("documentDevices",list);
        return data;
    }

    private static Map<String,Object> toCheckMap(Confirm confirm, List<Check> list,Integer page,Integer count,String time){
        Map<String,Object> data = new HashMap();
        data.put("title",confirm.getTitle());
        data.put("unit",confirm.getUnit());
        data.put("page",page);
        data.put("count",count);
        data.put("checks",list);
        data.put("time",time);
        return data;
    }


    private static Map<String,Object> toDestructionMap(Destruction destruction, List<DocumentDevice> list,String test,Integer page,Integer count){
        Map<String,Object> data = new HashMap();
        data.put("title",destruction.getTitle());
        data.put("ul",test);
        data.put("unitName",destruction.getDisposeUnitName());
        data.put("number",destruction.getNumber());
        Instant instant =  destruction.getTime().toInstant();
        String local1 = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        data.put("time",local1);
        data.put("page",page);
        data.put("count",count);
        List<DocumentDevice> list1=new ArrayList<>();
        AtomicInteger i= new AtomicInteger(1);
        list.forEach(
                documentDevice -> {
                    documentDevice.setCode(i.get());
                    i.set(i.get() + 1);
                    list1.add(documentDevice);
                }
        );
        data.put("documentDevices",list1);
        return data;
    }




    /**
     * freemarker渲染html  确认单据
     */
    public static String[] freeMarkerRenderConfirm(Confirm confirm,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;
        try {
            Template template = freemarkerCfg.getTemplate("bill2.html");
            template.setEncoding("UTF-8");

            List<DocumentDevice> list=confirm.getConfirmDevices();
            List<List<DocumentDevice>> listList=toConfirmList(list);
            int count=listList.size();
            Integer page=1;
            for (List<DocumentDevice> list1:listList) {
                String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                // 合并数据模型与模板
                FileWriter fileWriter = new FileWriter(new File(htmlname));
                template.process(toConfirmMap(confirm,list1,page,count),fileWriter);
                out.flush();
                strings[index]=htmlname;
                index++;
                page++;
            }
            return strings;
        } catch (Exception e) {
            log.error("[freeMarkerRenderConfirm] 方法找不到地址：{}",htmlPath);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }



    /**
     * freemarker渲染html  确认单据合并
     */
    public static String[] freeMarkerRenderConfirmMerge(Confirm confirm,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;
        try {
            Template template = freemarkerCfg.getTemplate("bill7.html");
            template.setEncoding("UTF-8");

            List<DocumentDevice> list=confirm.getConfirmDevices();
            List<List<DocumentDevice>> listList=toConfirmMergeList(list);
            int count=listList.size();
            Integer page=1;
            for (List<DocumentDevice> list1:listList) {
                String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                // 合并数据模型与模板
                FileWriter fileWriter = new FileWriter(new File(htmlname));
                template.process(toConfirmMap(confirm,list1,page,count),fileWriter);
                out.flush();
                strings[index]=htmlname;
                index++;
                page++;
            }
            return strings;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    public static List<List<DocumentDevice>> toConfirmMergeList(List<DocumentDevice> deviceList) throws UnsupportedEncodingException {
        List<List<DocumentDevice>> lists=new ArrayList<>();
        deviceList.stream().sorted(Comparator.comparing(DocumentDevice::getModel)).collect(Collectors.toList());
        List<DocumentDevice> documentDevices=new ArrayList<>();
        int i=0;
        for (int j=0;j< deviceList.size();j++){
            DocumentDevice documentDevice=deviceList.get(j);
            int  max= toMax2(documentDevice);
            if (i+max==14){
                String s=String.join("",toListString(documentDevice.getDeviceSerialNumber(),56));
                documentDevice.setOneCount(max);
                documentDevice.setDeviceSerialNumber(s);
                documentDevices.add(documentDevice);
                lists.add(documentDevices);
                documentDevices=new ArrayList<>();
                i=0;
            }else if (i+max>14){
                //当前页面少了多少行
                int differ=14-i;
                List<String> modelList= toListString(documentDevice.getModel(),13);
                List<String> seqList=toListString(documentDevice.getDeviceSerialNumber(),56);
                List<String> pasList=toListString(documentDevice.getParts(),13);
                DocumentDevice documentDevice1=new DocumentDevice();
                if (modelList.size()>differ){
                    documentDevice.setModel(String.join("",modelList.subList(0,differ)));
                    documentDevice1.setModel(String.join("",modelList.subList(differ,modelList.size())));
                }
                if (seqList.size()>differ){
                    documentDevice.setDeviceSerialNumber(String.join("",seqList.subList(0,differ)));
                    documentDevice1.setDeviceSerialNumber(String.join("",seqList.subList(differ,seqList.size())));

                }
                if (pasList.size()>differ){
                    documentDevice.setParts(String.join("",pasList.subList(0,differ)));
                    documentDevice1.setParts(String.join("",pasList.subList(differ,pasList.size())));
                }
                documentDevice.setOneCount(differ);
                documentDevices.add(documentDevice);
                lists.add(documentDevices);
                documentDevices=new ArrayList<>();
                documentDevice1.setOneCount(max-differ);
                documentDevices.add(documentDevice1);
                i=max-differ;
            }else {
                String s=String.join("",toListString(documentDevice.getDeviceSerialNumber(),56));
                documentDevice.setOneCount(max);
                documentDevice.setDeviceSerialNumber(s);
                documentDevices.add(documentDevice);
                i=i+max;
            }
        }
        if (documentDevices.size()!=0){
            lists.add(documentDevices);
        }
        return lists;

    }


    public static List<List<Check>> toCheckMergeList(List<DocumentDevice> deviceList,String unit) throws UnsupportedEncodingException {
        List<List<Check>> lists = new ArrayList<>();
        Map<String, Check> map = new HashMap<>();
        deviceList.forEach(
                documentDevice -> {
                    String key=documentDevice.getModel()+documentDevice.getParts()+documentDevice.getMatchingRangeName()+documentDevice.getIsPart();
                    if (map.containsKey(key)){
                        Check check=map.get(key);
                        check.setMatchingRangeName(documentDevice.getMatchingRangeName());
                        check.setIsPart(documentDevice.getIsPart());
                        check.setCount(check.getCount()+1);
                        List<String> strings=check.getStrings();
                        //添加下划线（送修设备）
                        String seqNumber;
                        if ("1".equals(documentDevice.getStatus())){
                            seqNumber="<span class=\"decorationLine\">"+documentDevice.getDeviceSerialNumber()+"</span>";
                        }else {
                            seqNumber=documentDevice.getDeviceSerialNumber();
                        }
                        strings.add(seqNumber);
//                        strings.add(documentDevice.getDeviceSerialNumber());
                        check.setStrings(strings);
                        map.put(key,check);
                    }else {
                        Check check= new Check();
                        List<String> strings=new ArrayList<>();
                        check.setCount(1);
                        check.setMatchingRangeName(documentDevice.getMatchingRangeName());
                        check.setIsPart(documentDevice.getIsPart());
                        check.setModel(documentDevice.getModel());
                        check.setName(documentDevice.getParts());
                        //添加下划线（送修设备）
                        String seqNumber;
                        if ("1".equals(documentDevice.getStatus())){
                            seqNumber="<span class=\"decorationLine\">"+documentDevice.getDeviceSerialNumber()+"</span>";
                        }else {
                            seqNumber=documentDevice.getDeviceSerialNumber();
                        }
                        strings.add(seqNumber);
//                        strings.add(documentDevice.getDeviceSerialNumber());
                        check.setStrings(strings);
                        map.put(key,check);
                    }
                }
        );
        List<Check> checkList=map.values().stream().sorted(Comparator.comparing(Check::getModel).thenComparing(Check::getMatchingRangeName).thenComparing(Check::getIsPart)).collect(Collectors.toList());
        map.clear();
        checkList.forEach(
                check -> {
                    String key=check.getModel()+check.getName();
                    if (map.containsKey(key)){
                        Check check1=map.get(key);
//                        check1.setMatchingRangeName(check.getMatchingRangeName());
//                        check1.setIsPart(check.getIsPart());
                        check1.setCount(check1.getCount()+check.getCount());
                        List<String> strings=check1.getStrings();
                        strings.addAll(check.getStrings());
                        check1.setStrings(strings);
                        map.put(key,check1);
                    }else {
                        Check check1= new Check();
                        check1.setCount(check.getCount());
                        check1.setMatchingRangeName(check.getMatchingRangeName());
                        check1.setIsPart(check.getIsPart());
                        check1.setModel(check.getModel());
                        check1.setName(check.getName());
                        List<String> strings = new ArrayList<>(check.getStrings());
                        check1.setStrings(strings);
                        map.put(key,check1);
                    }
                }
        );
        checkList=map.values().stream().sorted(Comparator.comparing(Check::getModel).thenComparing(Check::getMatchingRangeName).thenComparing(Check::getIsPart)).collect(Collectors.toList());
        List<Check> checkList2 = new ArrayList<>();
        int i = 0;
        for (int j = 0; j < checkList.size(); j++) {
            Check check = checkList.get(j);
            List<String> stringList = check.getStrings().stream().sorted(Comparator.comparing(String::toString)).collect(Collectors.toList());
            int max = toMaxList(check.getStrings()) + 1;

            if (i + max == 30) {
                check.setSeqStirng(toALLSeqStirng(stringList));
                check.setOneCount(max - 1);
                checkList2.add(check);
                lists.add(checkList2);
                checkList2 = new ArrayList<>();
                i = 0;
            } else if (i + max > 30) {
                //当前页面少了多少行
                int differ = 30 - i;
                check.setSeqStirng(toALLSeqStirng(stringList.subList(0, (differ-1) * 6)));
                check.setOneCount(differ - 1);
                checkList2.add(check);
                lists.add(checkList2);
                checkList2 = new ArrayList<>();
                List<String> strings = stringList.subList((differ-1) * 6, stringList.size());
                Integer max2 = toMaxList(strings);

                int count = (max2 % 30 > 0) ? max2 / 30 + 1 : max2 / 30;
                if (count != 1) {
                    int o = 1;
                    while (o <= count - 1) {
                        Check check1 = new Check();
                        check1.setSeqStirng(toALLSeqStirng(strings.subList((o - 1) * 6 * 30, o * 6 * 30)));
                        check1.setOneCount(30);
                        checkList2.add(check1);
                        lists.add(checkList2);
                        checkList2 = new ArrayList<>();
                        o++;
                    }
                    List<String> endList = strings.subList((count - 1) * 6 * 30, strings.size());
                    Integer max4 = toMaxList(endList);
                    if (max4 == 30) {
                        Check check1 = new Check();
                        check1.setSeqStirng(toALLSeqStirng(endList));
                        check1.setOneCount(30);
                        checkList2.add(check1);
                        lists.add(checkList2);
                        checkList2 = new ArrayList<>();
                        i = 0;
                    } else {
                        Check check1 = new Check();
                        check1.setOneCount(max4);
                        check1.setSeqStirng(toALLSeqStirng(endList));
                        checkList2.add(check1);
                        i = max4;
                    }
                } else {
                    Check check1 = new Check();
                    check1.setOneCount(toMaxList(strings));
                    check1.setSeqStirng(toALLSeqStirng(strings));
                    checkList2.add(check1);
                    i = toMaxList(strings);
                    if (i==30){
                        lists.add(checkList2);
                        checkList2=new ArrayList<>();
                        i=0;
                    }
                }
            } else {
                check.setSeqStirng(toALLSeqStirng(stringList));
                check.setOneCount(max - 1);
                checkList2.add(check);
                i = i + max;
            }
        }
        if (checkList2.size() != 0) {
            lists.add(checkList2);
        }
        return lists;
    }


    /**
     * freemarker渲染html  核查确认单据
     */
    public static String[] freeMarkerRenderVerification(Confirm confirm,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;
        try {
            Template template = freemarkerCfg.getTemplate("bill5.html");
            template.setEncoding("UTF-8");

            List<DocumentDevice> list=confirm.getConfirmDevices();
            List<List<DocumentDevice>> listList=toVerificationList(list);
            int count=listList.size();
            Integer page=1;
            for (List<DocumentDevice> list1:listList) {
                String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                // 合并数据模型与模板
                FileWriter fileWriter = new FileWriter(new File(htmlname));
                template.process(toConfirmMap(confirm,list1,page,count),fileWriter);
                out.flush();
                strings[index]=htmlname;
                index++;
                page++;
            }
            return strings;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }


    /**
     * freemarker渲染html  核查确认单据 修改
     */
    public static String[] freeMarkerRenderVerification2(Confirm confirm,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;
        Instant instant =  new Date().toInstant();
        String local1 = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        try {
            Template template = freemarkerCfg.getTemplate("bill10.html");
            template.setEncoding("UTF-8");

            List<DocumentDevice> list=confirm.getConfirmDevices();
            List<List<Check>> listList=toCheckMergeList(list,confirm.getUnit());
            int count=listList.size();
            Integer page=1;
            for (List<Check> list1:listList) {
                String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                // 合并数据模型与模板
                FileWriter fileWriter = new FileWriter(new File(htmlname));
                template.process(toCheckMap(confirm,list1,page,count,local1),fileWriter);
                out.flush();
                strings[index]=htmlname;
                index++;
                page++;
            }
            return strings;
        } catch (Exception e) {
            log.error("[freeMarkerRenderVerification2] 方法找不到地址：{}",htmlPath);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

//    /**
//     * 确认单据页面调用接口
//     */
//    public static FileRet createPdfConfirm(String[] htmlFiles,String path,String preview,){
//
//        Long startTime = System.currentTimeMillis();
//        Document document = new Document();
//        String name=UUID.randomUUID().toString()+".pdf";
//        String pdfPath=path+"confirm/"+name;
//        PdfCopy pdfCopy = null; //创建一个新文件
//        try {
//            pdfCopy = new PdfCopy(document, new FileOutputStream(pdfPath));
//            document.open();
//            for (String htmlFile : htmlFiles) {
//                if (htmlFile != null) {
//
//                    String url = new File(htmlFile).toURI().toURL().toString();
//                    ByteArrayOutputStream os = new ByteArrayOutputStream();
//                    ITextRenderer renderer = new ITextRenderer();
//                    renderer.setDocument(htmlFile);
//                    // 解决中文不显示问题
//                    ITextFontResolver fontResolver = renderer.getFontResolver();
//                    fontResolver.addFont(path+"fond/"+"simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//                    renderer.layout();
//                    renderer.createPDF(os);
//                    PdfReader pdfReader = new PdfReader(os.toByteArray());
//                    for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
//                        PdfImportedPage importedPage = pdfCopy.getImportedPage(pdfReader, i);
//                        pdfCopy.addPage(importedPage);
//                    }
//                    os.close();
//                }
//            }
//            Long endTime = System.currentTimeMillis();
//            System.out.print("Itext parse Html to Confirm Pdf End -> " + (endTime - startTime));
//            return new FileRet("", pdfPath, preview +"confirm/"+ name);
//        } catch (IOException | DocumentException e) {
//            e.printStackTrace();
//        } finally {
//            document.close();
//        }
//        return  new FileRet();
//    }



    /**
     * freemarker渲染html 销毁
     */
       public static String[] freeMarkerRenderDestruction(Destruction destruction,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;
        try {
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate("bill1.html");
            template.setEncoding("UTF-8");
            List<DocumentDevice> list=destruction.getConfirmDevices();
            List<List<DocumentDevice>> listList=toDocList(list);
            Integer count=listList.size();
            for (int i=1; i<=3; i++){
                Integer page=1;
                for (List<DocumentDevice> list1:listList) {
                    String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                    // 合并数据模型与模板
                    FileWriter fileWriter = new FileWriter(new File(htmlname));
                    template.process(toDestructionMap(destruction,list1,MAP1.get(i),page,count),fileWriter);
                    out.flush();
                    strings[index]=htmlname;
                    index++;
                    page++;
                }
            }
            return strings;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }


//    /**
//     * freemarker渲染html workHandoverDoc
//     */
//    public static String[] freeMarkerRenderWorkHandover(WorkHandoverDoc workHandoverDoc,String htmlPath) {
//        Writer out = new StringWriter();
//        String [] strings=new String[100000];
//        int index=0;
//        try {
//            // 获取模板,并设置编码方式
//            Template template = freemarkerCfg.getTemplate("bill3.html");
//            template.setEncoding("UTF-8");
//            List<WorkHandoverDevice> list = workHandoverDoc.getWorkHandoverDeviceList();
//            List<List<WorkHandoverDevice>> listList=toListWorkHandoverDevice(list);
//            Integer count=listList.size();
//            for (int i=1; i<=3; i++){
//                Integer page=1;
//                for (List<WorkHandoverDevice> list1:listList) {
//                    String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
//                    // 合并数据模型与模板
//                    FileWriter fileWriter = new FileWriter(new File(htmlname));
//                    template.process(toMapWork(workHandoverDoc,list1,MAP1.get(i),page,count),fileWriter);
//                    out.flush();
//                    strings[index]=htmlname;
//                    index++;
//                    page++;
//                }
//            }
//            return strings;
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                out.close();
//            } catch (IOException ex) {
//                ex.printStackTrace();
//            }
//        }
//        return null;
//    }


    private static Map<String,Object> toMapWork(WorkHandoverDoc workHandoverDoc,List<DocumentDevice> list,String test,Integer page,Integer count){
        Map<String,Object> data = new HashMap();
        data.put("unit",workHandoverDoc.getUnit());
        data.put("page",page);
        data.put("count",count);
//        AtomicInteger i= new AtomicInteger(1);
//        list.forEach(
//           workHandoverDevice -> {
//               workHandoverDevice.setCode(i.get());
//               i.set(i.get()+1);
//           }
//        );

        data.put("documentDevices",list);
        return data;
    }


    public static FileRet createPdfDestruction(String[] htmlFiles,String path,String preview,String folderName){

        Long startTime = System.currentTimeMillis();
        Document document = new Document();
        String name=UUID.randomUUID().toString()+".pdf";
        String pdfPath=path+folderName+name;
        PdfCopy pdfCopy = null; //创建一个新文件
        try {
            pdfCopy = new PdfCopy(document, new FileOutputStream(pdfPath));
            document.open();
            for (String htmlFile : htmlFiles) {
                if (htmlFile != null) {

                    String url = new File(htmlFile).toURI().toURL().toString();
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    ITextRenderer renderer = new ITextRenderer();
                    renderer.setDocument(htmlFile);
                    // 解决中文不显示问题
                    ITextFontResolver fontResolver = renderer.getFontResolver();
                    fontResolver.addFont(path+"fond/"+"simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                    renderer.layout();
                    renderer.createPDF(os);
                    PdfReader pdfReader = new PdfReader(os.toByteArray());
                    for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
                        PdfImportedPage importedPage = pdfCopy.getImportedPage(pdfReader, i);
                        pdfCopy.addPage(importedPage);
                    }
                    os.close();
                }
            }
            Long endTime = System.currentTimeMillis();
            System.out.print("Itext parse Html to Destruction Pdf  End -> " + (endTime - startTime));
            return new FileRet("", pdfPath, preview +folderName+ name);
        } catch (IOException | DocumentException | com.lowagie.text.DocumentException e) {
            e.printStackTrace();
        } finally {
            document.close();
        }
        return  new FileRet();
    }


//    public static FileRet createPdfWordHandover(String[] htmlFiles,String path,String preview){
//
//        Long startTime = System.currentTimeMillis();
//        Document document = new Document();
//        String name=UUID.randomUUID().toString()+".pdf";
//        String pdfPath=path+"wordHandover/"+name;
//        PdfCopy pdfCopy = null; //创建一个新文件
//        try {
//            pdfCopy = new PdfCopy(document, new FileOutputStream(pdfPath));
//            document.open();
//            for (String htmlFile : htmlFiles) {
//                if (htmlFile != null) {
//
//                    String url = new File(htmlFile).toURI().toURL().toString();
//                    ByteArrayOutputStream os = new ByteArrayOutputStream();
//                    ITextRenderer renderer = new ITextRenderer();
//                    renderer.setDocument(htmlFile);
//                    // 解决中文不显示问题
//                    ITextFontResolver fontResolver = renderer.getFontResolver();
//                    fontResolver.addFont(path+"fond/"+"simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//                    renderer.layout();
//                    renderer.createPDF(os);
//                    PdfReader pdfReader = new PdfReader(os.toByteArray());
//                    for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
//                        PdfImportedPage importedPage = pdfCopy.getImportedPage(pdfReader, i);
//                        pdfCopy.addPage(importedPage);
//                    }
//                    os.close();
//                }
//            }
//            Long endTime = System.currentTimeMillis();
//            System.out.print("Itext parse Html to Destruction Pdf  End -> " + (endTime - startTime));
//            return new FileRet("", pdfPath, preview +"wordHandover/"+ name);
//        } catch (IOException | DocumentException e) {
//            e.printStackTrace();
//        } finally {
//            document.close();
//        }
//        return  new FileRet();
//    }


    /**
     * 核查清单
     * @param deviceList
     * @return
     */
    private static List<List<DocumentDevice>> toVerificationList(List<DocumentDevice> deviceList){
        List<List<DocumentDevice>> lists=new ArrayList<>();
        deviceList= deviceList.stream().sorted(Comparator.comparing(DocumentDevice::getModel)).collect(Collectors.toList());
        List<DocumentDevice> documentDevices=new ArrayList<>();
        int i=0;
        Integer code=0;
        for (DocumentDevice documentDevice : deviceList) {
            int max = toVerificationMax(documentDevice);
            if (i + max == 34) {
                code++;
                documentDevice.setCode(code);
                documentDevices.add(documentDevice);
                lists.add(documentDevices);
                documentDevices = new ArrayList<>();
                i = 0;
            } else if (i + max > 34) {
                documentDevice.setCode(code);
                lists.add(documentDevices);
                documentDevices = new ArrayList<>();
                documentDevices.add(documentDevice);
                i = max;
            } else {
                documentDevice.setCode(code);
                documentDevices.add(documentDevice);
                i = i + max;
            }
        }
        if (documentDevices.size()!=0){
            lists.add(documentDevices);
        }
        return lists;

    }


    private static Integer toVerificationMax(DocumentDevice documentDevice){
        int partsCount=String_length(documentDevice.getParts());
        int deviceSerialNumberCount=String_length(documentDevice.getDeviceSerialNumber());
        int modelCount=String_length(documentDevice.getModel());
        int parts = (partsCount%17>0) ? partsCount/17 + 1 :  partsCount/17;
        int deviceSerialNumber=(deviceSerialNumberCount%22>0) ? deviceSerialNumberCount/22 + 1 :  deviceSerialNumberCount/22;
        int model=(modelCount%17>0) ? modelCount/17 + 1 :  modelCount/17;
        int  max=parts;
        //求最大
        if(max<deviceSerialNumber){
            max=deviceSerialNumber;
        }
        if(max<model) {
            max = model;
        }
        return max;
    }



    /**
     * 自查确认单据
     * @param deviceList
     * @return
     */
    private static List<List<DocumentDevice>> toConfirmList(List<DocumentDevice> deviceList){
        deviceList.stream().sorted(Comparator.comparing(DocumentDevice::getModel)).collect(Collectors.toList());
        Integer code=0;
        List<List<DocumentDevice>> lists=new ArrayList<>();
        List<DocumentDevice> documentDevices=new ArrayList<>();
        int i=0;
        for (DocumentDevice documentDevice : deviceList) {
            int max = toMax(documentDevice);
            if (i + max == 34) {
                code++;
                documentDevice.setCode(code);
                documentDevices.add(documentDevice);
                lists.add(documentDevices);
                documentDevices = new ArrayList<>();
                i = 0;
            } else if (i + max > 34) {
                code++;
                documentDevice.setCode(code);
                lists.add(documentDevices);
                documentDevices = new ArrayList<>();
                documentDevices.add(documentDevice);
                i = max;
            } else {
                code++;
                documentDevice.setCode(code);
                documentDevices.add(documentDevice);
                i = i + max;
            }
        }
        if (documentDevices.size()!=0){
            lists.add(documentDevices);
        }
        return lists;

    }


    private static int String_length(String value) {
        int valueLength = 0;
        if (value!=null) {
            String chinese = "[\u4e00-\u9fa5]";
            for (int i = 0; i < value.length(); i++) {
                String temp = value.substring(i, i + 1);
                if (temp.matches(chinese)) {
                    valueLength += 2;
                } else {
                    valueLength += 1;
                }
            }
        }
        return valueLength;
    }
    private static Integer toMax(DocumentDevice documentDevice){
        int partsCount=String_length(documentDevice.getParts());
        int deviceSerialNumberCount=String_length(documentDevice.getDeviceSerialNumber());
        int modelCount=String_length(documentDevice.getModel());
        int parts = (partsCount%20>0) ? partsCount/20 + 1 :  partsCount/20;
        int deviceSerialNumber=(deviceSerialNumberCount%22>0) ? deviceSerialNumberCount/22 + 1 :  deviceSerialNumberCount/22;
        int model=(modelCount%20>0) ? modelCount/20 + 1 :  modelCount/20;
        int  max=parts;
        //求最大
        if(max<deviceSerialNumber){
            max=deviceSerialNumber;
        }
        if(max<model) {
            max = model;
        }
        return max;
    }


    /**
     * 计算每一页打印的内容
     * 判断是否超过一页展示的最多的内容
     * 如大于
     *  直接生成一个页面的数据 放入到集合中 List<List<DocumentDevice>>
     *      不大于则计算相关的值，下一个内容
     * @param documentDevices
     * @return
     */
    private static List<List<DocumentDevice>> toList(List<DocumentDevice> documentDevices) {
        documentDevices=documentDevices.stream().sorted(Comparator.comparing(DocumentDevice::getLen).reversed()).collect(Collectors.toList());
        List<List<DocumentDevice>> lists=new ArrayList<>();
        List<DocumentDevice> list=new ArrayList<>();
        AtomicInteger count = new AtomicInteger();
        for (int i=0;i<documentDevices.size();i++){
            DocumentDevice documentDevice=documentDevices.get(i);
            int len=documentDevice.getDeviceSerialNumber().length();
            String deviceSerialNumber=documentDevice.getDeviceSerialNumber();
            if (len > 784){
                int page=0;
                int remainder = len % 784;
                int pageCount = (remainder > 0) ? len/784 + 1 :  len/784;
                while (page<pageCount-1) {
                    if (page==0) {
                        documentDevice.setDeviceSerialNumber(toString(documentDevice.getDeviceSerialNumber().substring(page * 784, (page + 1) * 784)));
                        list.add(documentDevice.toOneCount());
                        lists.add(list);
                    }else {
                        DocumentDevice documentDevice1=new DocumentDevice();
                        documentDevice1.setDeviceSerialNumber(toString(deviceSerialNumber.substring(page * 784, (page + 1) * 784)));
                        list.add(documentDevice1.toOneCount());
                        lists.add(list);
                    }
                    list = new ArrayList<>();
                    page++;
                }
                DocumentDevice documentDevice1=new DocumentDevice();
                documentDevice1.setDeviceSerialNumber(toString(deviceSerialNumber.substring((pageCount-1)*784, len)));
                list.add(documentDevice1.toOneCount());
                count.set(len-(pageCount-1)*784);
            }else if (len==784){
                documentDevice.setDeviceSerialNumber(toString(documentDevice.getDeviceSerialNumber()));
                list.add(documentDevice.toOneCount());
                lists.add(list);
                list = new ArrayList<>();
            }
            else {
                int totle=count.get()+len;
                if (totle > 784){
//                    if (len>56) {
                    if (784-count.get()>56) {
                        DocumentDevice documentDevice1 = new DocumentDevice();
                        documentDevice1.setDeviceSerialNumber(toString(documentDevice.getDeviceSerialNumber().substring(784 - count.get(), len)));
                        documentDevice.setDeviceSerialNumber(toString(documentDevice.getDeviceSerialNumber().substring(0, 784 - count.get())));
                        list.add(documentDevice.toOneCount());
                        lists.add(list);
                        list = new ArrayList<>();
                        list.add(documentDevice1.toOneCount());
                        int num = documentDevice1.getDeviceSerialNumber().length();
                        int yu = num % 56;
                        count.set(num + yu);
                    }else {
                        documentDevice.setDeviceSerialNumber(toString(documentDevice.getDeviceSerialNumber()));
                        list.add(documentDevice.toOneCount());
                        lists.add(list);
                        list = new ArrayList<>();
                        count.set(0);
//                        list.add(documentDevice);
                    }

                }else {
                    documentDevice.setDeviceSerialNumber(toString(documentDevice.getDeviceSerialNumber()));
                    list.add(documentDevice.toOneCount());
                    int yu=len%56;
                    totle=totle+(56-yu);
                    count.set(totle);
                }
            }
            if (list.size()==14){
                lists.add(list);
                list = new ArrayList<>();
                count.set(0);
            }
            if (i==documentDevices.size()-1){
                lists.add(list);
            }
        }
        return lists;
    }

    /**
     * 计算每一页打印的内容  （遗弃）
     * 判断是否超过一页展示的最多的内容
     * 如大于
     *  直接生成一个页面的数据 放入到集合中 List<List<DocumentDevice>>
     *      不大于则计算相关的值，下一个内容
     * @param workHandoverDevices 装备数据信息
     * @return
     */
    private static List<List<WorkHandoverDevice>> toListWorkHandoverDevice(List<WorkHandoverDevice> workHandoverDevices) {
        workHandoverDevices=workHandoverDevices.stream().sorted(Comparator.comparing(WorkHandoverDevice::getLen).reversed()).collect(Collectors.toList());
        List<List<WorkHandoverDevice>> lists=new ArrayList<>();
        List<WorkHandoverDevice> list=new ArrayList<>();
        AtomicInteger count = new AtomicInteger();
        int code=0;
        for (int i=0;i<workHandoverDevices.size();i++){
            WorkHandoverDevice workHandoverDevice=workHandoverDevices.get(i);
            int len=workHandoverDevice.getSeqs().length();
            String deviceSerialNumber=workHandoverDevice.getSeqs();

            if (len > 784){
                int page=0;
                int remainder = len % 784;
                int pageCount = (remainder > 0) ? len/784 + 1 :  len/784;
                while (page<pageCount-1) {
                    if (page==0) {
                        workHandoverDevice.setSeqs(workHandoverDevice.getSeqs().substring(page * 1568, (page + 1) * 1568));
                        code++;
                        workHandoverDevice.setCode(code);
                        list.add(workHandoverDevice);
                        lists.add(list);
                    }else {
                        WorkHandoverDevice workHandoverDevice1=new WorkHandoverDevice();
                        workHandoverDevice1.setSeqs(deviceSerialNumber.substring(page * 1568, (page + 1) * 1568));
                        code++;
                        workHandoverDevice1.setCode(code);
                        list.add(workHandoverDevice1);
                        lists.add(list);
                    }
                    list = new ArrayList<>();
                    page++;
                }
                WorkHandoverDevice workHandoverDevice1=new WorkHandoverDevice();
                workHandoverDevice1.setSeqs(deviceSerialNumber.substring((pageCount-1)*784, len));
                code++;
                workHandoverDevice1.setCode(code);
                list.add(workHandoverDevice1);
                count.set(len-(pageCount-1)*784);
            } else if (len==784){
                workHandoverDevice.setSeqs(toString(workHandoverDevice.getSeqs()));
                code++;
                workHandoverDevice.setCode(code);
                list.add(workHandoverDevice);
                lists.add(list);
                list=new ArrayList<>();
            }else {
                int totle=count.get()+len;
                 if (totle>784){
                    if (784-count.get()>56) {
                        WorkHandoverDevice workHandoverDevice1 = new WorkHandoverDevice();
                        workHandoverDevice1.setSeqs(toString(workHandoverDevice.getSeqs().substring(784 - count.get(), len)));
                        workHandoverDevice.setSeqs(toString(workHandoverDevice.getSeqs().substring(0, 784 - count.get())));
                        code++;
                        workHandoverDevice.setCode(code);
                        list.add(workHandoverDevice);
                        lists.add(list);
                        list = new ArrayList<>();
                        code++;
                        workHandoverDevice1.setCode(code);
                        list.add(workHandoverDevice1);
                        int num = workHandoverDevice1.getSeqs().length();
                        int yu = num % 56;
                        count.set(num + yu);
                    }else {
                        code++;
                        workHandoverDevice.setCode(code);
                        list.add(workHandoverDevice);
                        lists.add(list);
                        list = new ArrayList<>();
                        count.set(0);
                    }
                }else {
                     code++;
                     workHandoverDevice.setCode(code);
                    workHandoverDevice.setSeqs(toString(workHandoverDevice.getSeqs()));
                    list.add(workHandoverDevice);
                    int yu=len%56;
                    totle=totle+(56-yu);
                    count.set(totle);
                }
            }
            if (list.size()==14){
                lists.add(list);
                list = new ArrayList<>();
                count.set(0);
            }
            if (i==workHandoverDevices.size()-1){
                workHandoverDevice.setSeqs(toString(workHandoverDevice.getSeqs()));
                lists.add(list);
            }
        }
        return lists;
    }

    private static String toString(String str){
        int len=56;
        StringBuilder stringBuilder=new StringBuilder();
        if (str.length()>56){
            boolean falg=true;
            int i=0;
            while (falg){
                if ((i+1)*len>str.length()) {
                    stringBuilder.append(str.substring(i * len)).toString();
                    falg=false;
                }else {
                    stringBuilder.append(str, i*len, (i+1)*len).append("<br/>");
                    i++;
                }
            }
            return stringBuilder.toString();
        }else {
            return str;
        }
    }




    /**
     * freemarker渲染html
     */
    public static String[] freeMarkerRenderRevenue(RevenueEntity revenueEntity,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;
        try {
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate("bill4.html");
            template.setEncoding("UTF-8");

            List<Revenue> list=revenueEntity.getRevenueList();
            List<List<Revenue>> listList=toRevenueList2(list);
            int count=listList.size();
            Integer page=1;
            for (List<Revenue> list1:listList) {
                String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                // 合并数据模型与模板
                FileWriter fileWriter = new FileWriter(new File(htmlname));
                template.process(toMapRevenue(revenueEntity,list1,page,count),fileWriter);
                out.flush();
                strings[index]=htmlname;
                index++;
                page++;
            }
            return strings;
        } catch (Exception e) {
            log.error("[freeMarkerRenderRevenue] 方法找不到地址：{}",htmlPath);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }


    private static Map<String,Object> toMapRevenue(RevenueEntity revenueEntity,List<Revenue> list,Integer page,Integer count){
        Map<String,Object> data = new HashMap();

        data.put("title",revenueEntity.getTitle());
        data.put("revenueUnit",revenueEntity.getRevenueUnit());
        data.put("page",page);
        data.put("count",count);
        data.put("time",revenueEntity.getTime());
//        List<Revenue> list1=new ArrayList<>();
//        AtomicInteger i= new AtomicInteger(1);
//        list.forEach(
//                revenue -> {
//                    revenue.setCode(i.get());
//                    i.set(i.get() + 1);
//                    list1.add(revenue);
//                }
//        );
        data.put("revenues",list);
        return data;
    }


    public static List<List<Revenue>> toRevenueList2(List<Revenue> deviceList) throws UnsupportedEncodingException {
        List<List<Revenue>> lists=new ArrayList<>();
        List<Revenue> revenues=new ArrayList<>();
        deviceList=deviceList.stream().sorted(Comparator.comparing(Revenue::getModel).thenComparing(Revenue::getPart)).collect(Collectors.toList());
        Integer code=0;
        int i=0;
        for (int j=0;j< deviceList.size();j++){
            Revenue revenue=deviceList.get(j);
            int  max= toRevenueMax(revenue);
            if (i+max==18){
                revenue.setModel(String.join("",toListString(revenue.getModel(),17)));
                revenue.setDes(String.join("",toListString(revenue.getDes(),10)));
                revenue.setPart(String.join("",toListString(revenue.getPart(),17)));
                revenue.setOneCount(max);
                code++;
                revenue.setCode(code);
                revenues.add(revenue);
                lists.add(revenues);
                revenues = new ArrayList<>();
                i=0;
            }else if (i+max>18){
                //当前页面少了多少行
                int differ=18-i;
                List<String> modelList= toListString(revenue.getModel(),17);
                List<String> pasList=toListString(revenue.getPart(),17);
                List<String> desList=toListString(revenue.getDes(),10);
                Revenue revenue1=new Revenue();
                if (modelList.size()>differ){
                    revenue.setModel(String.join("",modelList.subList(0,differ)));
                    revenue1.setModel(String.join("",modelList.subList(differ,modelList.size())));
                }
                if (pasList.size()>differ){
                    revenue.setPart(String.join("",pasList.subList(0,differ)));
                    revenue1.setPart(String.join("",pasList.subList(differ,pasList.size())));
                }
                if (desList.size()>differ){
                    revenue.setDes(String.join("",desList.subList(0,differ)));
                    revenue1.setDes(String.join("",desList.subList(differ,desList.size())));
                }
                code++;
                revenue.setCode(code);
                revenue.setOneCount(differ);
                revenues.add(revenue);
                lists.add(revenues);
                revenues=new ArrayList<>();
                revenue1.setOneCount(max-differ);
                code++;
                revenue1.setCode(code);
                revenues.add(revenue1);
                i=max-differ;
            }else {
                code++;
                revenue.setModel(String.join("",toListString(revenue.getModel(),17)));
                revenue.setDes(String.join("",toListString(revenue.getDes(),10)));
                revenue.setPart(String.join("",toListString(revenue.getPart(),17)));
                revenue.setCode(code);
                revenue.setOneCount(max);
                revenues.add(revenue);
                i=i+max;
            }
        }
        if (revenues.size()!=0){
            lists.add(revenues);
        }
        return lists;

    }

    private static List<List<Revenue>> toRevenueList(List<Revenue> deviceList){
        List<List<Revenue>> lists=new ArrayList<>();
        List<Revenue> revenues=new ArrayList<>();
        int i=0;
        for (Revenue revenue : deviceList) {
            int max = toRevenueMax(revenue);
            if (i + max == 20) {
                revenues.add(revenue);
                lists.add(revenues);
                revenues = new ArrayList<>();
                i = 0;
            } else if (i + max > 20) {
                lists.add(revenues);
                revenues = new ArrayList<>();
                revenues.add(revenue);
                i = max;
            } else {
                revenues.add(revenue);
                i = i + max;
            }
        }
        if (revenues.size()!=0){
            lists.add(revenues);
        }
        return lists;

    }

    private static Integer toRevenueMax(Revenue revenue){
        int partsCount=String_length(revenue.getPart());
        int modelCount=String_length(revenue.getModel());
        int desCount=String_length(revenue.getDes());
        int parts = (partsCount%17>0) ? partsCount/17 + 1 :  partsCount/17;
        int model=(modelCount%17>0) ? modelCount/17 + 1 :  modelCount/17;
        int des=(desCount%10>0) ? desCount/10 + 1 :  desCount/10;

        int  max=parts;
        //求最大
        if(max<model){
            max=model;
        }
        if (max<des){
            max=des;
        }
        return max;
    }



    //----------------------导出设备信息相关接口-------------------
    /**
     * freemarker渲染html  核查确认单据 修改
     */

    public static String[] freeMarkerRenderExportDevice(Confirm confirm,String htmlPath) {
        Writer out = new StringWriter();
        String [] strings=new String[100000];
        int index=0;
        Instant instant =  new Date().toInstant();
        String local1 = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        try {
            Template template = freemarkerCfg.getTemplate("bill11.html");
            template.setEncoding("UTF-8");

            List<DocumentDevice> list=confirm.getConfirmDevices();
            List<List<ExportDevice>> listList=toExportDeviceList(list,confirm.getUnit());
            int count=listList.size();
            Integer page=1;
            for (List<ExportDevice> list1:listList) {
                String htmlname=htmlPath+ UUID.randomUUID().toString()+".html";
                // 合并数据模型与模板
                FileWriter fileWriter = new FileWriter(new File(htmlname));
                template.process(toExportDeviceMap(confirm,list1,page,count,local1),fileWriter);
                out.flush();
                strings[index]=htmlname;
                index++;
                page++;
            }
            return strings;
        } catch (Exception e) {
            log.error("[freeMarkerRenderExportDevice] 方法找不到地址：{}",htmlPath);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    public static List<List<ExportDevice>> toExportDeviceList(List<DocumentDevice> deviceList, String unit) throws UnsupportedEncodingException {
        List<List<ExportDevice>> lists = new ArrayList<>();
        Map<String, ExportDevice> map = new HashMap<>();
        int pageSize=20;
        int seqPageSize=9;
        deviceList.forEach(
                documentDevice -> {
                    String key = documentDevice.getModel() + documentDevice.getParts()+documentDevice.getStore()+documentDevice.getOwnUnit();
                    if (map.containsKey(key)) {
                        ExportDevice check = map.get(key);
                        check.setCount(check.getCount() + 1);
                        List<String> strings = check.getStrings();
//                        strings.add(documentDevice.getDeviceSerialNumber());
                        //添加下划线（送修设备）
                        String seqNumber;
                        if ("1".equals(documentDevice.getStatus())){
                            seqNumber="<span class=\"decorationLine\">"+documentDevice.getDeviceSerialNumber()+"</span>";
                        }else {
                            seqNumber=documentDevice.getDeviceSerialNumber();
                        }
                        strings.add(seqNumber);
                        check.setStrings(strings);
                        map.put(key, check);
                    } else {
                        ExportDevice check = new ExportDevice();
                        List<String> strings = new ArrayList<>();
                        check.setCount(1);
                        check.setStore(documentDevice.getStore());
                        check.setOwnUnit(documentDevice.getOwnUnit());
                        check.setType(documentDevice.getType());
                        check.setModel(documentDevice.getModel());
                        check.setName(documentDevice.getParts());
                        //添加下划线（送修设备）
                        String seqNumber;
                        if ("1".equals(documentDevice.getStatus())){
                            seqNumber="<span class=\"decorationLine\">"+documentDevice.getDeviceSerialNumber()+"</span>";
                        }else {
                            seqNumber=documentDevice.getDeviceSerialNumber();
                        }
                        strings.add(seqNumber);
//                        strings.add(documentDevice.getDeviceSerialNumber());
                        check.setStrings(strings);
                        map.put(key, check);
                    }
                }
        );
        List<ExportDevice> checkList = map.values().stream().sorted(Comparator.comparing(ExportDevice::getModel).thenComparing(ExportDevice::getName)).collect(Collectors.toList());
        List<ExportDevice> checkList2 = new ArrayList<>();
        int i = 0;
        for (int j = 0; j < checkList.size(); j++) {
            ExportDevice check = checkList.get(j);
            List<String> stringList = check.getStrings().stream().sorted(Comparator.comparing(String::toString)).collect(Collectors.toList());
            int oneMax=toDeviceMax(check.getName(),check.getModel(),check.getOwnUnit(),check.getStore());
            int max = toMaxDeviceList(check.getStrings()) + oneMax;

            if (i + max == pageSize) {
                check.setSeqStirng(toALLDeviceSeqStirng(stringList));
                check.setOneCount(max - oneMax);
                check.setTitleCount(oneMax);
                checkList2.add(check);
                lists.add(checkList2);
                checkList2 = new ArrayList<>();
                i = 0;
            } else if (i + max > pageSize) {
                //当前页面少了多少行
                int differ = pageSize - i;
                int oneDiffer=0;
                List<String> modelList= toListString(check.getModel(),20);
                List<String> nameList=toListString(check.getName(),20);
                List<String> ownNameList= toListString(check.getOwnUnit(),20);
                List<String> storeList=toListString(check.getStore(),20);
                ExportDevice oneCheck=new ExportDevice();
                if (differ > oneMax){
                    if (differ-oneMax>max-oneMax) {
                        check.setSeqStirng(toALLDeviceSeqStirng(stringList.subList(0, stringList.size())));
                        stringList=new ArrayList<>();
                    }else {
                        check.setSeqStirng(toALLDeviceSeqStirng(stringList.subList(0, (differ-oneMax)*seqPageSize)));
                        stringList=stringList.subList((differ-oneMax)*seqPageSize,stringList.size());
                    }
                    check.setOneCount(differ-oneMax);
                    check.setTitleCount(oneMax);
                    oneCheck.setTitleCount(1);
                }else {
                    oneDiffer=oneMax-differ;
                    check.setTitleCount(oneMax-oneDiffer);
                    check.setOneCount(0);
                    if (modelList.size()>differ){
                        check.setModel(String.join("",modelList.subList(0,differ)));
                        oneCheck.setModel(String.join("",modelList.subList(differ,modelList.size())));
                    }else {
                        check.setModel(String.join("",modelList.subList(0,modelList.size())));
                    }

                    if (nameList.size()>differ){
                        check.setName(String.join("",nameList.subList(0,differ)));
                        oneCheck.setName(String.join("",nameList.subList(differ,nameList.size())));
                    }else {
                        check.setName(String.join("",nameList.subList(0,nameList.size())));

                    }
                    if (ownNameList.size()>differ){
                        check.setOwnUnit(String.join("",ownNameList.subList(0,differ)));
                        oneCheck.setOwnUnit(String.join("",ownNameList.subList(differ,ownNameList.size())));
                    }else {

                        check.setOwnUnit(String.join("",ownNameList.subList(0,ownNameList.size())));

                    }
                    if (storeList.size()>differ){
                        check.setStore(String.join("",storeList.subList(0,differ)));
                        oneCheck.setStore(String.join("",storeList.subList(differ,storeList.size())));
                    }else {
                        check.setTitleCount(storeList.size());
                        check.setStore(String.join("",storeList.subList(0,storeList.size())));
                    }
                    oneCheck.setTitleCount(oneMax-differ);
                    check.setTitleCount(differ-oneDiffer);
                }
                checkList2.add(check);
                lists.add(checkList2);
                checkList2 = new ArrayList<>();
                int max2 = toMaxDeviceList(stringList);
                if (max2+oneDiffer >pageSize) {
                    oneCheck.setOneCount(pageSize - oneDiffer);
                    oneCheck.setSeqStirng(toALLDeviceSeqStirng(stringList.subList(0, pageSize - oneDiffer)));
                    checkList2.add(oneCheck);
                    lists.add(checkList2);
                    checkList2 = new ArrayList<>();
                    stringList = stringList.subList(pageSize - oneDiffer, stringList.size());
                    max2 = toMaxDeviceList(stringList);
                    int count = (max2 % pageSize > 0) ? max2 / pageSize + 1 : max2 / pageSize;
                    if (count != 1) {
                        int o = 1;
                        while (o <= count - 1) {
                            ExportDevice check1 = new ExportDevice();
                            check1.setSeqStirng(toALLDeviceSeqStirng(stringList.subList((o - 1) * seqPageSize * pageSize, o * seqPageSize * pageSize)));
                            check1.setOneCount(pageSize);
                            checkList2.add(check1);
                            lists.add(checkList2);
                            checkList2 = new ArrayList<>();
                            o++;
                        }
                        List<String> endList = stringList.subList((count - 1) * seqPageSize * pageSize, stringList.size());
                        Integer max4 = toMaxDeviceList(endList);
                        int count1 = (max4 % pageSize > 0) ? max4 / pageSize + 1 : max4 / pageSize;
                        if (count1 == pageSize) {
                            ExportDevice check1 = new ExportDevice();
                            check1.setSeqStirng(toALLDeviceSeqStirng(endList));
                            check1.setOneCount(pageSize);
                            checkList2.add(check1);
                            lists.add(checkList2);
                            checkList2 = new ArrayList<>();
                            i = 0;
                        } else {
                            ExportDevice check1 = new ExportDevice();
                            check1.setOneCount(max4);
                            check1.setSeqStirng(toALLDeviceSeqStirng(endList));
                            checkList2.add(check1);
                            i = max4;
                        }
                    } else {
                        ExportDevice check1 = new ExportDevice();
                        check1.setOneCount(toMaxDeviceList(stringList));
                        check1.setSeqStirng(toALLDeviceSeqStirng(stringList));
                        checkList2.add(check1);
                        i = toMaxDeviceList(stringList);
                    }
                }else {
                    int count=toMaxDeviceList(stringList);
                    oneCheck.setOneCount(count);
                    oneCheck.setSeqStirng(toALLDeviceSeqStirng(stringList));
                    checkList2.add(oneCheck);
                    i=count+oneDiffer;
                }
            } else {
                check.setTitleCount(oneMax);
                List<String> modelList= toListString(check.getModel(),20);
                List<String> nameList=toListString(check.getName(),20);
                List<String> ownNameList= toListString(check.getOwnUnit(),20);
                List<String> storeList=toListString(check.getStore(),20);
                check.setStore(String.join("",storeList));
                check.setOwnUnit(String.join("",ownNameList));
                check.setModel(String.join("",modelList));
                check.setName(String.join("",nameList));
                check.setSeqStirng(toALLDeviceSeqStirng(stringList));
                check.setOneCount(max - oneMax);
                checkList2.add(check);
                i = i + max;
            }
        }
        if (checkList2.size() != 0) {
            lists.add(checkList2);
        }
        return lists;
    }

    private static Map<String,Object> toExportDeviceMap(Confirm confirm, List<ExportDevice> list,Integer page,Integer count,String time){
        Map<String,Object> data = new HashMap();
        data.put("title",confirm.getTitle());
        data.put("unit",confirm.getUnit());
        data.put("page",page);
        data.put("count",count);
        data.put("checks",list);
        data.put("time",time);
        return data;
    }
    private static int toMaxDeviceList(List<String> strings){
        Integer count=strings.size();
        return (count%9>0) ? count/9 + 1 : count/9;
    }

    private static int toDeviceMax(String parts,String model,String ownName,String des){
        int partsCount=String_length(parts);
        int modelCount=String_length(model);
        int ownNameCount=String_length(ownName);
        int desCount=String_length(des);
        int partsMax = (partsCount%20>0) ? partsCount/20 + 1 :  partsCount/20;
        int modelMax=(modelCount%20>0) ? modelCount/20 + 1 :  modelCount/20;
        int ownNameMax = (ownNameCount%20>0) ? ownNameCount/20 + 1 :  ownNameCount/20;
        int desMax=(desCount%20>0) ? desCount/20 + 1 :  desCount/20;
        int  max=partsMax;
        //求最大
        if(max<modelMax){
            max=modelMax;
        }
        if (max<ownNameMax){
            max=ownNameMax;
        }
        if (max<desMax){
            max=desMax;
        }
        return max;
    }


    private static String toALLDeviceSeqStirng(List<String> strings){
        int page=9;
        int count=toMaxDeviceList(strings);
        StringBuilder allStirng= new StringBuilder();
        for (int i=1;i<=count;i++){
            if (i!=count) {
                allStirng.append(seqToString(strings.subList((i - 1) * page, i * page)));
            }else {
                allStirng.append(seqToString(strings.subList((i - 1) * page, strings.size())));
            }
        }
        return allStirng.toString();
    }

    /**
     *  工作交接计算每一页数据
     * @param deviceList
     * @return
     * @throws UnsupportedEncodingException
     */
    public static List<List<DocumentDevice>> toWorkHandoverDeviceList(List<DocumentDevice> deviceList) throws UnsupportedEncodingException {
        List<List<DocumentDevice>> lists=new ArrayList<>();
        List<DocumentDevice> documentDevices=new ArrayList<>();
        deviceList=deviceList.stream().sorted(Comparator.comparing(DocumentDevice::getModel).thenComparing(DocumentDevice::getParts)).collect(Collectors.toList());
        Integer code=0;
        int i=0;
        for (int j=0;j< deviceList.size();j++){
            DocumentDevice documentDevice=deviceList.get(j);
            int  max= toWorkHandoverMax(documentDevice);
            if (i+max==15){
                String s=String.join("",toListString(documentDevice.getDeviceSerialNumber(),56));
                documentDevice.setOneCount(max);
                documentDevice.setModel(String.join("",toListString(documentDevice.getModel(),17)));
                documentDevice.setParts(String.join("",toListString(documentDevice.getParts(),17)));
                documentDevice.setRemark(String.join("",toListString(documentDevice.getRemark(),15)));
                documentDevice.setDeviceSerialNumber(s);
                code++;
                documentDevice.setCode(code);
                documentDevices.add(documentDevice);
                lists.add(documentDevices);
                documentDevices=new ArrayList<>();
                i=0;
            }else if (i+max>15){
                //当前页面少了多少行
                int differ=15-i;
                List<String> modelList= toListString(documentDevice.getModel(),17);
                List<String> seqList=toListString(documentDevice.getDeviceSerialNumber(),56);
                List<String> pasList=toListString(documentDevice.getParts(),17);
                List<String> remarkList=toListString(documentDevice.getRemark(),15);
                DocumentDevice documentDevice1=new DocumentDevice();
                if (modelList.size()>differ){
                    documentDevice.setModel(String.join("",modelList.subList(0,differ)));
                    documentDevice1.setModel(String.join("",modelList.subList(differ,modelList.size())));
                }else {
                    documentDevice.setModel(String.join("",modelList.subList(0,modelList.size())));

                }
                if (seqList.size()>differ){
                    documentDevice.setDeviceSerialNumber(String.join("",seqList.subList(0,differ)));
                    documentDevice1.setDeviceSerialNumber(String.join("",seqList.subList(differ,seqList.size())));
                }else {
                    documentDevice.setDeviceSerialNumber(String.join("",seqList.subList(0,seqList.size())));

                }
                if (pasList.size()>differ){
                    documentDevice.setParts(String.join("",pasList.subList(0,differ)));
                    documentDevice1.setParts(String.join("",pasList.subList(differ,pasList.size())));
                }else {
                    documentDevice.setParts(String.join("",pasList.subList(0,pasList.size())));

                }
                if (remarkList.size()>differ){
                    documentDevice.setRemark(String.join("",remarkList.subList(0,differ)));
                    documentDevice1.setRemark(String.join("",remarkList.subList(differ,remarkList.size())));
                }else {
                    documentDevice.setRemark(String.join("",remarkList));
                }
                code++;
                documentDevice.setCode(code);
                documentDevice.setOneCount(differ);
                documentDevices.add(documentDevice);
                lists.add(documentDevices);
                documentDevices=new ArrayList<>();
                code++;
                documentDevice1.setCode(code);
                documentDevice1.setOneCount(max-differ);
                documentDevices.add(documentDevice1);
                i=max-differ;
            }else {
                String s=String.join("",toListString(documentDevice.getDeviceSerialNumber(),56));
                code++;
                documentDevice.setModel(String.join("",toListString(documentDevice.getModel(),17)));
                documentDevice.setParts(String.join("",toListString(documentDevice.getParts(),17)));
                documentDevice.setRemark(String.join("",toListString(documentDevice.getRemark(),15)));
                documentDevice.setCode(code);
                documentDevice.setOneCount(max);
                documentDevice.setDeviceSerialNumber(s);
                documentDevices.add(documentDevice);
                i=i+max;
            }
        }
        if (documentDevices.size()!=0){
            lists.add(documentDevices);
        }
        return lists;

    }

    private static Integer toWorkHandoverMax(DocumentDevice documentDevice){
        int partsCount=String_length(documentDevice.getParts());
        int deviceSerialNumberCount=String_length(documentDevice.getDeviceSerialNumber());
        int modelCount=String_length(documentDevice.getModel());
        int remarkCount=String_length(documentDevice.getRemark());
        int parts = (partsCount%17>0) ? partsCount/17 + 1 :  partsCount/17;
        int deviceSerialNumber=(deviceSerialNumberCount%56>0) ? deviceSerialNumberCount/56 + 1 :  deviceSerialNumberCount/56;
        int model=(modelCount%17>0) ? modelCount/17 + 1 :  modelCount/17;
        int remark=(remarkCount%15>0) ? remarkCount/15 + 1 :  remarkCount/15;
        int  max=parts;
        //求最大
        if(max<deviceSerialNumber){
            max=deviceSerialNumber;

        }
        if(max<model) {
            max = model;
        }
        if (max<remark){
            max=remark;
        }

        return max;
    }


    /**
     * freemarker渲染html workHandoverDoc
     */
    public static String[] freeMarkerRenderWorkHandover2(WorkHandoverDoc workHandoverDoc,String htmlPath) {
        Writer out = new StringWriter();
        String[] strings = new String[100000];
        int index = 0;
        try {
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate("bill13.html");
            template.setEncoding("UTF-8");
            List<DocumentDevice> list = workHandoverDoc.getWorkHandoverDeviceList();
            List<List<DocumentDevice>> listList = toWorkHandoverDeviceList(list);
            Integer count = listList.size();
            for (int i = 1; i <= 3; i++) {
                Integer page = 1;
                for (List<DocumentDevice> list1 : listList) {
                    String htmlname = htmlPath + UUID.randomUUID().toString() + ".html";
                    // 合并数据模型与模板
                    FileWriter fileWriter = new FileWriter(new File(htmlname));
                    template.process(toMapWork(workHandoverDoc, list1, MAP1.get(i), page, count), fileWriter);
                    out.flush();
                    strings[index] = htmlname;
                    index++;
                    page++;
                }
            }
            return strings;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }
}
