国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

執法文書打印的實現(二):基于freemaker技術生成可打印的word文檔

2019-11-14 22:27:11
字體:
來源:轉載
供稿:網友
執法文書打印的實現(二):基于freemaker技術生成可打印的Word文檔

執法文書打印的實現(二)

基于freemaker技術生成可打印的word文檔:

基于FreeMarker生成word.doc文檔是一項比較成熟的技術。前承上篇博客(),這個方案只能在windows下部署,不支持linux。這方面的示例網上已經很多了,我也簡單上下代碼好了(深入的話,我也不了解(汗)。

略過樣例測試,首先需要確定word模板。比如: 現場檢查筆錄.doc ,打開文件,把需要替換的內容加上標記 格式:${插值},并設置好頁眉等樣式:

其次:將word模板另存為xml 2003,并用xml編輯器打開,這里推薦使用XMLSPY ,這個工具打開xml的顯示易于查找和編輯。打開xml,編輯word另存為后插值分開的部分,重新合并(這個在上篇博客已經詳細描述,這里就不贅述了)。

最后把xcjc.xml修改為xcjc.ftl,模板文件也就準備好了,下面就需要添加具體的java代碼。

在項目中導入對應的jar包,書寫生成word.docx文檔的方法:

public  String createWord(Map dataMap,String templateName){             String fileName=UUID.randomUUID().toString()+".docx";             try {                 //創建配置實例                  Configuration configuration = new Configuration(Configuration.VERSION_2_3_21);                 //設置編碼                 configuration.setDefaultEncoding("UTF-8");                                  //ftl模板文件統一放至com.sinosoft.zhifa.common.commonPRint.ftlFile.包下面                 //configuration.setClassForTemplateLoading(PrintUtil.class,"/com/sinosoft/zhifa/common/commonPrint/ftlFile/");                 //這種方法取不到已修改的模板                 //設置從文件系統中加載模板      ftlFilePath文件在系統的路徑                 configuration.setDirectoryForTemplateLoading(new File(ftlFilePath));                 //獲取模板                  Template template = configuration.getTemplate(templateName);                                  //輸出文件 File.separator分隔符unix為/ window為//                 File outFile = new File(wordFilePath+File.separator+fileName);                                  //如果輸出目標文件夾不存在,則創建                 if (!outFile.getParentFile().exists()){                     outFile.getParentFile().mkdirs();                 }                                  //將模板和數據模型合并生成文件                  Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));                 //生成文件                 template.process(dataMap, out);                                  //關閉流                 out.flush();                 out.close();             } catch (Exception e) {                 e.printStackTrace();             }             return fileName;         }
生成word

其中,dataMap是要替換的數據map,這個map的key是模板的插值,value是具體的數據,而且value不能為null,下面是示例:

 Map dataMap=new HashMap();            dataMap.put("被檢查單位",(String)scenMap.get("ENT_NAME")==null?"  ":(String)scenMap.get("ENT_NAME"));//ENT_NAME    北京恩彼凱化肥廠            dataMap.put("營業執照",(String)scenMap.get("BUSINESS_LICENSE")==null?"  ":(String)scenMap.get("BUSINESS_LICENSE"));//BUSINESS_LICENSE    這是我們的營業執照BUSINESS_LICENSE    這是我們的營業執照            dataMap.put("編號",(String)scenMap.get("BUSINESS_LICENSE_ID")==null?"  ":(String)scenMap.get("BUSINESS_LICENSE_ID"));//BUSINESS_LICENSE_ID    xxxxxxx            dataMap.put("組織機構代碼",(String)scenMap.get("ORGANIZATION_CODE")==null?"  ":(String)scenMap.get("ORGANIZATION_CODE"));//ORGANIZATION_CODE    123123412384組織機構代碼            dataMap.put("地址",(String)scenMap.get("ILLEGALACT_ADDRESS")==null?"  ":(String)scenMap.get("ILLEGALACT_ADDRESS"));//ILLEGALACT_ADDRESS    北京市朝陽區霄云路            dataMap.put("電話",(String)scenMap.get("ILLEGALACT_PHONE")==null?"  ":(String)scenMap.get("ILLEGALACT_PHONE"));//ILLEGALACT_PHONE    13366009185            dataMap.put("法定代表人",(String)scenMap.get("LEGAL_REPRESENTATIVE")==null?"  ":(String)scenMap.get("LEGAL_REPRESENTATIVE"));//LEGAL_REPRESENTATIVE    法定負責人            dataMap.put("性別",(String)scenMap.get("GENDER")==null?"  ":(String)scenMap.get("GENDER"));//GENDER    男            dataMap.put("職務",(String)scenMap.get("DUTY")==null?"  ":(String)scenMap.get("DUTY"));//DUTY    總經理
datamap示例

由于插值{現場檢查}是一個富文本,需要圖文混排,我在這里是解析數據庫的html的標簽,根據需要向xcjc.ftl添加插值,并向dataMap中寫入對應的key、value:

解析html中的圖片并調用修改ftl的方法:

//用圖片分割后的富文本

String [] imgs=inspection.split("<img//s+[^>]*/>|<img//s+[^>]*>[^<]*</img>");

//如果有圖片,則重新生成ftl文件

XmlUtils xmlutils=new XmlUtils(getRequest());

Map newMap=xmlutils.xmlHandle("xcjc_copy.xml",imgs,pictList);

修改ftl的具體實現:

public Map xmlHandle(String xmlfilepath, String[] imgs,            List<String> pictList) {        Map<String, String> pictMap = new HashMap<String, String>();        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();        try {            DocumentBuilder db = dbf.newDocumentBuilder();            File file = new File(ftlFilePath + fileS + xmlfilepath);            document = db.parse(file);            NodeList nodelist = document.getElementsByTagName("w:p");            Node baseNode = null;// 基于此節點添加節點信息            Node parentNode = null;// 在此節點下添加節點信息            for (int i = 0; i < nodelist.getLength(); i++) {                baseNode = nodelist.item(i);                Short eNode = Node.ELEMENT_NODE;                // 節點類型是節點,并且節點id:basewp                if (eNode.equals(baseNode.getNodeType())                        && "basewp".equalsIgnoreCase(((Element) baseNode)                                .getAttribute("id"))) {                    parentNode = baseNode.getParentNode();                    break;                }                if (i == nodelist.getLength() - 1) {                    System.out.println("沒有找到指定類型的節點");                    return null;                }            }            Map dataMap = new HashMap<String, String>();            int pictNum = 0;            // 拼裝要插入的xml節點:富文本是圖文并排,需要多次插入:解析這個富文本的工作要做,數據庫存儲的是html,需要的是純文本+圖片            for (int i = 0; i < imgs.length; i++) {                if (imgs[i] != null) {                    String xcjqText = imgs[i].replaceAll("<[^<>]*>|<|>", "");                    // 添加文本標簽                    // 給文本標簽模板賦值                    Node node = null;                    node = XmlUtils.getextNode("檢查情況文本"+i);                    parentNode.insertBefore(node, baseNode);                    pictMap.put("檢查情況文本"+i,xcjqText);                }                if (pictList.size() > pictNum) {                    // 解析圖片:圖片寬高                    String pictId = null;                    String pictWidth = null;                    String pictHeight = null;                    Pattern pt = Pattern.compile("http:[^/"']*");// 圖片鏈接                                                                    // http:/i/eg_mouse.jpg?id=xxxxx                    Matcher m = pt.matcher(pictList.get(pictNum));                    while (m.find()) {                        pictId = m.group().split("=")[1];// 圖片UUID                    }                    Pattern ptw = Pattern.compile("width(:|=)/"?//d*");                    Matcher mw = ptw.matcher(pictList.get(pictNum));                    while (mw.find()) {                        pictWidth = mw.group().split("=/"?|:")[1];// 圖片寬度數字部分                    }                    Pattern pth = Pattern.compile("height(:|=)/"?//d*");                    Matcher mh = pth.matcher(pictList.get(pictNum));                    while (mh.find()) {                        pictHeight = mh.group().split("=/"?|:")[1];// 圖片高度數字部分                    }                    // 請求圖片數據轉String(數據庫或文件系統),請求失敗則不添加圖片標簽,go on                    // 要返回圖片的備用寬度,高度,如果從img標簽中取到,則不用這個寬高,否則使用                    String pictD[] = this.getBase64PictStr(pictId);                    if (pictWidth == null) {                        pictWidth = pictD[0];                        pictHeight = pictD[1];                    }                    // 給圖片模板賦值                    // pt=px乘以3/4。                    String pictW = Integer.parseInt(pictWidth) * 3 / 4 + "";                    String pictH = Integer.parseInt(pictHeight) * 3 / 4 + "";                    String puuid = "現場檢查"+pictNum;//UUID.randomUUID().toString()  不能使用uuid其中的字符會被ftl模板錯誤解析                    pictMap.put(puuid, pictD[2]);                    // 添加圖片標簽                    Node node = null;                    node = XmlUtils.getPicNode(puuid, pictW, pictH,(pictNum+1+""));                    parentNode.insertBefore(node, baseNode);                    pictNum++;                    if (i == imgs.length - 1 && pictNum < pictList.size() - 1) {                        // 繼續添加圖片                    }                }            }            // 利用transformer對象將修改后的文檔重新輸出            TransformerFactory tFactory = TransformerFactory.newInstance();            Transformer transformer = tFactory.newTransformer();            DOMSource source = new DOMSource(document);            // 將xml文檔保存為ftl            StreamResult result = new StreamResult(new java.io.File(ftlFilePath                    + File.separator + "xcjc_copy.ftl"));            transformer.transform(source, result);        } catch (ParserConfigurationException e) {            // TODO 自動生成的 catch 塊            // e.printStackTrace();            System.out.println("xml配置有錯誤:ParserConfigurationException");        } catch (SAXException e) {            // TODO 自動生成的 catch 塊            // e.printStackTrace();            System.out.println("解析文件xml內容失敗");        } catch (IOException e) {            // TODO 自動生成的 catch 塊            // e.printStackTrace();            System.out.println(e + "讀取文件失敗");        } catch (TransformerConfigurationException e) {            // TODO 自動生成的 catch 塊            // e.printStackTrace();            System.out.println("轉換對象創建失敗");        } catch (TransformerException e) {            // TODO 自動生成的 catch 塊            // e.printStackTrace();            System.out.println("輸出文件失敗");        }        return pictMap;    }
xmlHandle

在這個實現中,調用了2個私有方法,分別是添加文本節點:getextNode和添加圖片節點:getPicNode,其中圖片數據必須是base64碼的:getBase64PictStr 

static Node getPicNode(String PictWordID, String picWidth, String picHeight,String picID) {        // 一級節點        // wp 節點及屬性        Element wpe = document.createElement("w:p");        wpe.setAttribute("wsp:rsidR", "00172C3B");        wpe.setAttribute("wsp:rsidRDefault", "00B7682D");        wpe.setAttribute("wsp:rsidP", "00172C3B");        // 二級節點        Element wppre = document.createElement("w:pPr");        Element wre = document.createElement("w:r");        wre.setAttribute("wsp:rsidRPr", "00974FA3");        wpe.appendChild(wppre);        wpe.appendChild(wre);        // 三級節點        Element wwindowcontrole = document.createElement("w:widowControl");        Element wjce = document.createElement("w:jc");        wjce.setAttribute("w:val", "left");        Element wrpre = document.createElement("w:rPr");        Element wrpre2 = document.createElement("w:rPr");        Element wpicte = document.createElement("w:pict");        wppre.appendChild(wwindowcontrole);        wppre.appendChild(wjce);        wppre.appendChild(wrpre);        wre.appendChild(wrpre2);        wre.appendChild(wpicte);        // 四級節點:處理方式改為順序        Element wrFontse = document.createElement("w:rFonts");        wrFontse.setAttribute("w:ascii", "宋體");        wrFontse.setAttribute("w:h-ansi", "宋體");        wrFontse.setAttribute("w:cs", "宋體");        wrpre.appendChild(wrFontse);        Element wxfonte = document.createElement("wx:font");        wxfonte.setAttribute("wx:val", "宋體");        wrpre.appendChild(wxfonte);        Element wkerne = document.createElement("w:kern");        wkerne.setAttribute("w:val", "0");        wrpre.appendChild(wkerne);        Element wsze = document.createElement("w:sz");        wsze.setAttribute("w:val", "24");        wrpre.appendChild(wsze);        Element wszcse = document.createElement("w:sz-cs");        wszcse.setAttribute("w:val", "24");        wrpre.appendChild(wszcse);        Element wnoProof = document.createElement("w:noProof");        wrpre2.appendChild(wnoProof);        Element vshapetype = document.createElement("v:shapetype");        vshapetype.setAttribute("id", "_x0000_t75");// //////////////////////v:stroke        vshapetype.setAttribute("coordsize", "21600,21600");        vshapetype.setAttribute("o:spt", "75");        vshapetype.setAttribute("o:preferrelative", "t");        vshapetype.setAttribute("path", "m@4@5l@4@11@9@11@9@5xe");        vshapetype.setAttribute("filled", "f");        vshapetype.setAttribute("stroked", "f");        wpicte.appendChild(vshapetype);        Element vstroke = document.createElement("v:stroke");        vstroke.setAttribute("joinstyle", "miter");        vshapetype.appendChild(vstroke);        Element vformulas = document.createElement("v:formulas");        vshapetype.appendChild(vformulas);        Element vf = document.createElement("v:f");        vf.setAttribute("eqn", "if lineDrawn pixelLineWidth 0");        vformulas.appendChild(vf);        Element vf2 = document.createElement("v:f");        vf2.setAttribute("eqn", "sum @0 1 0");        vformulas.appendChild(vf2);        Element vf3 = document.createElement("v:f");        vf3.setAttribute("eqn", "sum 0 0 @1");        vformulas.appendChild(vf3);        Element vf4 = document.createElement("v:f");        vf4.setAttribute("eqn", "prod @2 1 2");        vformulas.appendChild(vf4);        Element vf5 = document.createElement("v:f");        vf5.setAttribute("eqn", "prod @3 21600 pixelWidth");        vformulas.appendChild(vf5);        Element vf6 = document.createElement("v:f");        vf6.setAttribute("eqn", "prod @3 21600 pixelHeight");        vformulas.appendChild(vf6);        Element vf7 = document.createElement("v:f");        vf7.setAttribute("eqn", "sum @0 0 1");        vformulas.appendChild(vf7);        Element vf8 = document.createElement("v:f");        vf8.setAttribute("eqn", "prod @6 1 2");        vformulas.appendChild(vf8);        Element vf9 = document.createElement("v:f");        vf9.setAttribute("eqn", "prod @7 21600 pixelWidth");        vformulas.appendChild(vf9);        Element vf10 = document.createElement("v:f");        vf10.setAttribute("eqn", "sum @8 21600 0");        vformulas.appendChild(vf10);        Element vf11 = document.createElement("v:f");        vf11.setAttribute("eqn", "prod @7 21600 pixelHeight");        vformulas.appendChild(vf11);        Element vf12 = document.createElement("v:f");        vf12.setAttribute("eqn", "sum @10 21600 0");        vformulas.appendChild(vf12);        Element vpath = document.createElement("v:path");        vpath.setAttribute("o:extrusionok", "f");        vpath.setAttribute("gradientshapeok", "t");        vpath.setAttribute("o:connecttype", "rect");        vshapetype.appendChild(vpath);        Element olock = document.createElement("o:lock");        olock.setAttribute("v:ext", "edit");        olock.setAttribute("aspectratio", "t");        vshapetype.appendChild(olock);        Element wbinData = document.createElement("w:binData");        wbinData.setAttribute("w:name", "wordml://0300000"+picID+".png");//修改圖片的src和w:name解決只加載第一張圖片的問題        wbinData.setAttribute("xml:space", "preserve");        wpicte.appendChild(wbinData);        Text pictText = document.createTextNode("${" + PictWordID + "}");// 這兒可以添加圖片定位參數        wbinData.appendChild(pictText);        Element vshape = document.createElement("v:shape");// 指定圖片id和寬高           vshape.setAttribute("id", PictWordID);//圖片id需要動態傳值,多個圖片現在只加載同一個        vshape.setAttribute("o:spid", "_x0000_i1028");        vshape.setAttribute("type", "#_x0000_t75");// picWidth        // vshape.setAttribute("style","width:358.4pt;height:535.7pt;visibility:visible;mso-wrap-style:square");        vshape.setAttribute("style", "width:" + picWidth + "pt;height:"                + picHeight + "pt;visibility:visible;mso-wrap-style:square");        Element vimagedata = document.createElement("v:imagedata");        vimagedata.setAttribute("src", "wordml://0300000"+picID+".png");        vimagedata.setAttribute("o:title", "");        vshape.appendChild(vimagedata);        wpicte.appendChild(vshape);        return wpe;    }
getPicNode

static Node getextNode(String wordtext1) {        // 一級節點        // wp 節點及屬性        Element wpe = document.createElement("w:p");        wpe.setAttribute("wsp:rsidP", "008027B0");        wpe.setAttribute("wsp:rsidR", "008027B0");        wpe.setAttribute("wsp:rsidRDefault", "008027B0");        wpe.setAttribute("wsp:rsidRPr", "006B689C");        // 二級節點及屬性        Element wpPr = document.createElement("w:pPr");        Element wr = document.createElement("w:r");        wr.setAttribute("wsp:rsidRPr", "006B689C");        wpe.appendChild(wpPr);        wpe.appendChild(wr);        // 三級節點 順序添加        //wppr節點及子節點        Element wspacing = document.createElement("w:spacing");        wspacing.setAttribute("w:line", "500");        wspacing.setAttribute("w:line-rule", "exact");        wpPr.appendChild(wspacing);        Element wrPr = document.createElement("w:rPr");        wpPr.appendChild(wrPr);        Element wrFonts = document.createElement("w:rFonts");        wrFonts.setAttribute("w:ascii", "仿宋_GB2312");        wrFonts.setAttribute("w:cs", "仿宋_GB2312");        wrPr.appendChild(wrFonts);        Element wxfont = document.createElement("wx:font");        wxfont.setAttribute("wx:val", "仿宋_GB2312");        wrPr.appendChild(wxfont);        Element wu = document.createElement("w:u");//和下面的代碼一起控制文字下面是否有下劃線        wu.setAttribute("w:val", "single");//這里設置下劃線為單線        wrPr.appendChild(wu);        //wr節點及子節點        Element wrPr1 = document.createElement("w:rPr");        wr.appendChild(wrPr1);        Element wrFonts1 = document.createElement("w:rFonts");        wrFonts1.setAttribute("w:ascii", "仿宋_GB2312");        wrFonts1.setAttribute("w:cs", "仿宋_GB2312");        wrPr1.appendChild(wrFonts1);        Element wxfont1 = document.createElement("wx:font");        wxfont1.setAttribute("wx:val", "仿宋_GB2312");        wrPr1.appendChild(wxfont1);        Element wu1 = document.createElement("w:u");//和下面的代碼一起控制文字下面是否有下劃線        wu1.setAttribute("w:val", "single");//這里設置下劃線為單線        wrPr1.appendChild(wu1);        Element wt = document.createElement("w:t");//創建要插入文本的節點        Text wordtext=document.createTextNode("${" + wordtext1 + "}");//要插入文本的標記        wt.appendChild(wordtext);        wr.appendChild(wt);        return wpe;    }
getextNode
public String[] getBase64PictStr(String pictID) {        byte[] data = null;        String[] wh = new String[3];        Connection conn;        Statement stmt = null;        PreparedStatement ps = null;        ResultSet rs = null;        // 這個sql應該是動態獲取的        String sql = "select image from picc where id='"+pictID+"'";//2e30826eba714a909758c2bfff8f4875        DataSource dataSource = DataSourceFactory.defaultFactory                .getDataSource("dataSource");        try {            conn = dataSource.getConnection();            stmt = conn.createStatement();            rs = stmt.executeQuery(sql);            if (rs.next()) {                Blob blob = rs.getBlob("image");// IMAGE                data = blob.getBytes(1, (int) blob.length());                BufferedImage bis = ImageIO                        .read(new ByteArrayInputStream(data));                int wid = bis.getWidth();                wh[0] = wid + "";                int hei = bis.getHeight();                wh[1] = hei + "";                BASE64Encoder encoder = new BASE64Encoder();                String str = encoder.encode(data);                wh[2] = str;// 編碼后的圖片字符串                // System.out.println(str);            }        } catch (SQLException e1) {            e1.printStackTrace();            System.out.println("創建數據庫連接失敗");        } catch (IOException e) {            System.out.println("轉換圖片失敗");            // e.printStackTrace();        }        return wh;    }
getBase64PictStr

下一篇博客要寫下word轉pdf/png的方法,jodconver這個jar包用過2個版本,3.0的很不成熟,不推薦。這個方法生成word現在沒有在項目中使用,有問題互相探討。


上一篇:Maven依賴

下一篇:Effective Java

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 密山市| 华池县| 达孜县| 中阳县| 苗栗市| 鹤岗市| 安西县| 密山市| 崇州市| 阿克苏市| 固始县| 荔波县| 安康市| 松溪县| 民县| 浦北县| 南充市| 铜梁县| 龙江县| 潞城市| 玛沁县| 吉隆县| 临邑县| 玉屏| 横峰县| 拜城县| 邹平县| 东源县| 凤山市| 吉木萨尔县| 社旗县| 临武县| 澄城县| 博乐市| 芷江| 邵阳市| 沧源| 辽宁省| 上蔡县| 福清市| 英山县|