java代碼:html轉pdf & docx 轉pdf

  1. html轉pdf:
    前端用富文本編輯內容,傳入html後端通過工具類進行轉換,直接上代碼
/**
     * html轉pdf
     * @param content
     * @param fileName
     * @param rootPath
     * @param staticDomain
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static FileInfoVo htmlToPdf(String content, String fileName, String rootPath, String staticDomain) throws IOException, DocumentException {

        String title = System.currentTimeMillis() + "" + RandomUtils.nextInt(1000, 9999) + fileName.substring(fileName.indexOf("."));

        val css = getCssStr(content);
        val str = PDF_START_BODY.concat(content).concat(PDF_END_BODY);
        ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes());
        Document document = new Document();

        document.setMargins(30, 30, 30, 30);
        ByteArrayInputStream is = null;
        if (!"".equals(css)) {
            is = new ByteArrayInputStream(css.getBytes());
        }
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(PDF_STREAM.concat(title)));
        document.open();
        //將html格式寫入文檔
        //加載字體
        XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider() {
            @Override
            public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color) {

                //你的字體文件的位置
                String yaHeiFontName = PDF_FONTS;
                //如果是ttc需要這一行,ttf不需要
                yaHeiFontName += ",1";
                com.lowagie.text.Font yaHeiFont;
                Font font = null;
                try {
                    font = new Font(BaseFont.createFont(yaHeiFontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED));
                    font.setStyle(style);
                    font.setColor(color);
                    if (size>0){
                        font.setSize(size);
                    }
                } catch (DocumentException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return font;
            }
        };

        XMLWorkerHelper.getInstance().parseXHtml(writer, document, in, is, fontProvider);
        document.close();

        FileInfoVo fileInfo = new FileInfoVo();
        //服務器文件路徑
        String path = Constants.DMSFILE_UPLOAD_PATH;

        try {
            String realPath = path.concat(Constants.LINK_SYMBOL).concat(DateFormatUtils.format(System.currentTimeMillis(), "yyyyMM"));
            String pathName = rootPath.concat(realPath);
            InputStream input = new FileInputStream(new File(PDF_STREAM.concat(title)));
            val uploadRst = ftpService.storeFile(pathName, title, input);
            if (uploadRst) {
                fileInfo.setDomain(staticDomain);
                fileInfo.setUrl(realPath.concat(Constants.LINK_SYMBOL).concat(title));
                fileInfo.setFileName(fileName);
                return fileInfo;
            }
        } catch (Exception e) {
            return new FileInfoVo();
        }
        return fileInfo;
    }

2.注意事項:

    // 字體
    private static  final String PDF_FONTS = "/usr/share/fonts/simsun.ttc";
    // 頭部樣式
    private static  final String PDF_START_BODY = "<body style=\"font-family:微軟雅黑\">";
    // 頭部樣式
    private static  final String PDF_END_BODY = "<body>";

爲什麼需要添加這兩項呢?
3.在liunx服務器上的字體是不支持windows字體的,需要在liunx服務器上預先放置支持的字體。不放會導致html轉換pdf,中文消失。
4.需要在html代碼前和後分別加上樣式,不然會報錯。

5.常量根據自己的情況定義,我這裏需要先保存一個臨時文件。

    // 源文件
    private static  final String PDF_STREAM = "/data/temp";
    // 源文件2
    private static  final String PDF_STREAM_2 = "/data/temp/";

6.根據自己情況,選擇是否要上傳。我這裏是需要上傳。

// 文件上傳自定義
private static FtpService ftpService;

8.獲取css樣式

 /**
     * 獲取css樣式
     *
     * @param content
     * @return
     */
    public static String getCssStr(String content) {

        String reg = "\\.([a-zA-Z0-9_]*)\\s*(\\{[^\\}]*\\})";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(content);
        String cssStr = "";
        while (m.find()) {
            cssStr += m.group() + "  ";
        }
        System.out.println(cssStr);
        return cssStr;
    }

9.docx 轉pdf

/**
     * docxpdf
     * @param fileName
     * @param rootPath
     * @param staticDomain
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static FileInfoVo docxToPdf(String filePath, String fileName, String rootPath, String staticDomain) throws IOException, DocumentException {

        String title = System.currentTimeMillis() + "" + RandomUtils.nextInt(1000, 9999);

        FileInfoVo fileInfo = new FileInfoVo();
        //服務器文件路徑
        String path = Constants.DMSFILE_UPLOAD_PATH;

        String word = filePath;
        String pdf = PDF_STREAM_2+title+".pdf";
        XDocService service = new XDocService();
        try {
            service.to(word, new File(pdf));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            String realPath = path.concat(Constants.LINK_SYMBOL).concat(DateFormatUtils.format(System.currentTimeMillis(), "yyyyMM"));
            String pathName = rootPath.concat(realPath);
            InputStream input = new FileInputStream(new File(pdf));
            val uploadRst = ftpService.storeFile(pathName, title+".pdf", input);
            if (uploadRst) {
                fileInfo.setDomain(staticDomain);
                fileInfo.setUrl(staticDomain.concat(realPath.concat(Constants.LINK_SYMBOL).concat(title+".pdf")));
                fileInfo.setFileName(fileName);
                return fileInfo;
            }
        } catch (Exception e) {
            return new FileInfoVo();
        }
        return fileInfo;
    }

10.docx轉pdf爲了保證樣式一點都不會錯亂!!!用的XDocService ,真是一大坑啊

package com.zjsft.openapi.utils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * XDoc服務
 * @author xdoc
 * @version 12.2.5
 */
public class XDocService {
    /**
     * 默認服務器地址
     */
    public static String DEFAULT_URL = "http://www.xdocin.com";
    /**
     * 默認賬號口令
     */
    public static String DEFAULT_KEY = "";
    /**
     * XDOC服務地址
     */
    private String url;
    /**
     * XDOC服務口令
     */
    private String key;
    /**
     * 服務地址
     * @return
     */
    public String getUrl() {
        return url;
    }
    /**
     * 服務地址
     * @param url
     */
    public void setUrl(String url) {
        this.url = url;
    }
    /**
     * 賬號口令
     * @return
     */
    public String getKey() {
        return key;
    }
    /**
     * 賬號口令
     * @param key
     */
    public void setKey(String key) {
        this.key = key;
    }
    /**
     * 構造器
     */
    public XDocService() {
        this(DEFAULT_URL, DEFAULT_KEY);
    }
    /**
     * 構造器
     * @param url 服務地址
     */
    public XDocService(String url) {
        this(url, DEFAULT_KEY);
    }
    /**
     * 構造器
     * @param url 服務地址
     * @param key 賬號
     */
    public XDocService(String url, String key) {
        this.url = url;
        this.key = key;
    }
    /**
     * 轉換爲其它格式文件
     * @param xdoc xdoc
     * @param file 其它格式文件,如:a.pdf
     * @throws IOException
     */
    public void to(File xdoc, File file) throws IOException {
        to(xdoc.getAbsolutePath(), file);
    }
    /**
     * 轉換爲其它格式文件
     * @param xdoc xdoc文本<br>
     *        URL:文檔URL地址,格式支持:xdoc、json、docx、epub、txt、rtf等,支持datauri協議,可傳遞二進制數據,支持本地文件<br>
     *        純文本:以"text:"開頭的文本<br>
     *        JSON:符合XDOC-JSON規範的JSON文本<br>
     *        XML:符合XDOC-XML規範的XML文本<br>
     *        HTML:用html標籤括起來的html文本,如:&lt;html&gt;&lt;h1&gt;Hello&lt;/h1&gt;&lt;/html&gt;
     * @param file 其它格式文件,如:a.pdf
     * @throws IOException
     */
    public void to(String xdoc, File file) throws IOException {
        to(xdoc, new FileOutputStream(file), getFormat(file.getName()));
    }
    /**
     * 轉換爲其它格式,保存到指定流中
     * @param xdoc xdoc
     * @param out 輸出目標,OutputStream或HttpServletResponse
     * @param format format
     * @throws IOException
     */
    public void to(String xdoc, Object out, String format) throws IOException {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("_func", "to");
        param.put("_xdoc", xdoc);
        param.put("_format", format);
        invoke(checkParam(param), out);
    }
    /**
     * 轉換爲其它格式併發送
     * @param xdoc xdoc
     * @param to 目標,支持ftp、http、mail、datauri等
     * @param format format
     * @throws IOException
     */
    public String to(String xdoc, String to, String format) throws IOException {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("_func", "to");
        param.put("_xdoc", xdoc);
        param.put("_to", to);
        param.put("_format", format);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(checkParam(param), out);
        return new String(out.toByteArray(), "UTF-8");
    }
    /**
     * 運行xdoc
     * @param xdoc xdoc
     * @param param 參數
     * @param file 目標文件
     * @throws IOException
     */
    public void run(File xdoc, Map<String, Object> param, File file) throws IOException {
        if (!param.containsKey("_xformat")) {
            param.put("_xformat", getFormat(file.getName()));
        }
        run(xdoc.getAbsolutePath(), param, file);
    }
    /**
     * 運行xdoc
     * @param xdoc xdoc
     * @param param 參數
     * @param file 目標文件
     * @throws IOException
     */
    public void run(String xdoc, Map<String, Object> param, File file) throws IOException {
        run(xdoc, param, new FileOutputStream(file), getFormat(file.getName()));
    }
    /**
     * 運行xdoc
     * @param xdoc xdoc
     * @param param 參數
     * @param out 輸出目標,OutputStream或HttpServletResponse
     * @param format 目標格式
     * @throws IOException
     */
    public void run(String xdoc, Map<String, Object> param, Object out, String format) throws IOException {
        param.put("_func", "run");
        param.put("_xdoc", xdoc);
        param.put("_format", format);
        invoke(checkParam(param), out);
    }
    /**
     * 運行xdoc併發送
     * @param xdoc xdoc
     * @param param 參數
     * @param to 目標,支持ftp、http、mail、datauri等
     * @param format 目標格式
     * @throws IOException
     */
    public String run(String xdoc, Map<String, Object> param, String to, String format) throws IOException {
        param.put("_func", "run");
        param.put("_xdoc", xdoc);
        param.put("_to", to);
        param.put("_format", format);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(checkParam(param), out);
        return new String(out.toByteArray(), "UTF-8");
    }
    /**
     * 運行註解XDoc
     * @param obj
     * @param file
     * @throws IOException
     */
    public void run(Object obj, File file) throws IOException {
        run(obj, new FileOutputStream(file), getFormat(file.getName()));
    }
    /**
     * 運行註解XDoc
     * @param obj
     * @param out 目標流
     * @param format 目標格式
     * @throws IOException
     */
    public void run(Object obj, Object out, String format) throws IOException {
        run(obj, out, null, format);
    }
    /**
     * 運行註解XDoc
     * @param obj
     * @param to 目標,支持ftp、http、mail、datauri等
     * @param format 目標格式
     * @throws IOException
     */
    public void run(Object obj, String to, String format) throws IOException {
        run(obj, null, to, format);
    }
    private void run(Object obj, Object out, String to, String format) throws IOException {
        String xurl = "";
        XDoc xdoc = obj.getClass().getAnnotation(XDoc.class);
        if (xdoc != null) {
            xurl = xdoc.value();
        }
        if (xurl.length() == 0) {
            xurl = "./" + obj.getClass().getSimpleName() + ".xdoc";
        }
        Field[] fields = obj.getClass().getDeclaredFields();
        boolean hasXParam = false;
        XParam xParam;
        Map<String, Object> param = new HashMap<String, Object>();
        String name;
        Object value;
        for (Field field : fields) {
            xParam = field.getAnnotation(XParam.class);
            if (xParam != null) {
                hasXParam = true;
                name = xParam.value();
                if (name.length() == 0) {
                    name = field.getName();
                }
                try {
                    field.setAccessible(true);
                    value = field.get(obj);
                    if (name.equals("_xdoc")) {
                        xurl = String.valueOf(value);
                    } else {
                        param.put(name, value);
                    }
                } catch (Exception e) {
                    throw new IOException(e);
                }
            }
        }
        if (!hasXParam) { //沒有指定xparam,傳入所有屬性
            for (Field field : fields) {
                try {
                    field.setAccessible(true);
                    param.put(field.getName(), field.get(obj));
                } catch (Exception e) {
                    throw new IOException(e);
                }
            }
        }
        if (out != null) {
            this.run(xurl, param, out, format);
        } else {
            this.run(xurl, param, to, format);
        }
    }
    /**
     * 招呼
     * @return
     * @throws IOException
     */
    public boolean hi() throws IOException {
        return invokeStringFunc("hi").equals("ok");
    }
    /**
     * 關於
     */
    public String about() throws IOException {
        return invokeStringFunc("about");
    }
    /**
     * 動態口令
     * @return
     * @throws IOException
     */
    public String dkey() throws IOException {
        return invokeStringFunc("dkey");
    }
    /**
     * 修改口令
     * @return
     * @throws IOException
     */
    public String ckey() throws IOException {
        return invokeStringFunc("ckey");
    }
    /**
     * 註冊
     * @param mail 郵件
     * @return
     * @throws IOException
     */
    public String reg(String mail) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "reg");
        params.put("_mail", mail);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return (String) parse(out.toByteArray());
    }
    /**
     * 賬戶信息
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public Map<String, String> acc() throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "acc");
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return (Map<String, String>) parse(out.toByteArray());
    }
    /**
     * 基於ID上傳
     * @param id
     * @param file
     * @return
     * @throws IOException
     */
    public void sup(String id, File file) throws IOException {
        sup(id, toDataURI(file.getAbsolutePath()));
    }
    /**
     * 基於ID上傳
     * @param id
     * @param in
     * @throws IOException
     */
    public void sup(String id, InputStream in) throws IOException {
        sup(id, toDataURI(in));
    }
    private void sup(String id, String dataUri) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "sup");
        params.put("_id", id);
        params.put("_data", dataUri);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        parse(out.toByteArray());
    }
    /**
     * 基於ID下載
     * @param id
     * @param file
     * @throws IOException
     */
    public void sdown(String id, File file) throws IOException {
        sdown(id, new FileOutputStream(file));
    }
    /**
     * 基於ID下載
     * @param id
     * @param out 輸出目標,OutputStream或HttpServletResponse
     * @throws IOException
     */
    public void sdown(String id, Object out) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "sdown");
        params.put("_id", id);
        invoke(params, out);
    }
    /**
     * 基於ID刪除
     * @param id
     * @return
     * @throws IOException
     */
    public boolean sremove(String id) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "sremove");
        params.put("_id", id);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return parse(out.toByteArray()).equals("ok");
    }
    /**
     * 創建目錄
     * @param dir
     * @return
     * @throws IOException
     */
    public boolean mkdir(String dir) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "mkdir");
        params.put("_dir", dir);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return parse(out.toByteArray()).equals("ok");
    }
    /**
     * 目錄列表
     * @param dir
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public List<Map<String, String>> dirlist(String dir) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "dirlist");
        params.put("_dir", dir);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return (List<Map<String, String>>) parse(out.toByteArray());
    }
    /**
     * 文件列表
     * @param dir
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public List<Map<String, String>> filelist(String dir) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "filelist");
        params.put("_dir", dir);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return (List<Map<String, String>>) parse(out.toByteArray());
    }
    /**
     * 上傳
     * @param dir
     * @param file
     * @return
     * @throws IOException
     */
    public void up(String dir, File file) throws IOException {
        up(dir, toDataURI(file.getAbsolutePath()));
    }
    /**
     * 上傳
     * @param dir
     * @param in
     * @throws IOException
     */
    public void up(String dir, InputStream in) throws IOException {
        up(dir, toDataURI(in));
    }
    private void up(String dir, String dataUri) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "up");
        params.put("_dir", dir);
        params.put("_data", dataUri);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        parse(out.toByteArray());
    }
    /**
     * 下載
     * @param dir
     * @param file
     * @throws IOException
     */
    public void down(String dir, File file) throws IOException {
        down(dir, new FileOutputStream(file));
    }
    /**
     * 下載
     * @param dir
     * @param out 輸出目標,OutputStream或HttpServletResponse
     * @throws IOException
     */
    public void down(String dir, Object out) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "down");
        params.put("_dir", dir);
        invoke(params, out);
    }
    /**
     * 刪除
     * @param dir
     * @return
     * @throws IOException
     */
    public boolean remove(String dir) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "remove");
        params.put("_dir", dir);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return parse(out.toByteArray()).equals("ok");
    }
    /**
     * 文件是否存在
     * @param dir
     * @return
     * @throws IOException
     */
    public boolean exists(String dir) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "exists");
        params.put("_dir", dir);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return parse(out.toByteArray()).equals("true");
    }
    /**
     * 查詢表單數據
     * @param xdoc 表單文檔路徑
     * @param keyword 數據過濾關鍵字
     * @return
     * @throws IOException
     */
    public List<Map<String, String>> xquery(String xdoc, String keyword) throws IOException {
        return this.xquery(xdoc, keyword, -1, -1);
    }
    /**
     * 查詢表單數據
     * @param xdoc 表單文檔路徑
     * @param keyword 數據過濾關鍵字
     * @param offset 數據偏移,與“_rows”參數一起使用,用於分頁,如:&_offset=20&&_rows=10表示每頁10條,取第3頁
     * @param rows 數量
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public List<Map<String, String>> xquery(String xdoc, String keyword, int offset, int rows) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "xquery");
        params.put("_xdoc", xdoc);
        params.put("_keyword", keyword);
        params.put("_offset", String.valueOf(offset));
        params.put("_rows", String.valueOf(rows));
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return (List<Map<String, String>>) parse(out.toByteArray());
    }
    /**
     * 基於ID的XDATA轉換
     * @param id
     * @param format 目標格式:xml、json、csv
     * @return
     * @throws IOException
     */
    public String xdataById(String id, String format) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "xdata");
        params.put("_id", id);
        params.put("_format", format);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return (String) parse(out.toByteArray());
    }
    /**
     * XDATA轉換
     * @param data xdata數據,格式:xml、json、csv
     * @param format 目標格式:xml、json、csv
     * @return
     * @throws IOException
     */
    public String xdata(String xdata, String format) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", "xdata");
        params.put("_xdata", xdata);
        params.put("_format", format);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return (String) parse(out.toByteArray());
    }
    /**
     * 通過url地址調用服務,支持本地文件xdoc和xdata
     * @param args
     */
    public static void main(String[] args) {
        if (args.length > 0 && args[0].length() > 0) {
            String url = args[0];
            if (url.charAt(0) == '@') { //命令文件
                File cmdFile = new File(url.substring(1));
                try {
                    FileReader reader = new FileReader(cmdFile);
                    url = (new BufferedReader(reader)).readLine();
                    reader.close();
                    cmdFile.delete();
                } catch (Exception e) {
                    e.printStackTrace();
                    return;
                }
            }
            String server = DEFAULT_URL;
            int pos = url.indexOf('?');
            if (pos > 0) {
                server = url.substring(0, pos);
                if (server.endsWith("/xdoc")) {
                    server = server.substring(0, server.length() - 5);
                }
                url = url.substring(pos + 1);
            }
            String xkey = "";
            try {
                String[] params = url.split("&");
                Map<String, String> map = new HashMap<String, String>();
                String key, value;
                String to = null;
                for (int i = 0; i < params.length; i++) {
                    pos = params[i].indexOf('=');
                    if (pos > 0) {
                        key = decode(params[i].substring(0, pos));
                        value = decode(params[i].substring(pos + 1));
                        if (isXDocData(key, value)) {
                            value = toDataURI(value);
                        } else if (key.indexOf("@file") > 0) {
                            key = key.substring(0, key.length() - 5);
                            value = toDataURI(value);
                        } else if (key.equals("_key")) {
                            xkey = value;
                            continue;
                        } else if (key.equals("_to") && isFile(value)) {
                            to = value;
                            continue;
                        }
                        map.put(key, value);
                    }
                }
                if (!map.containsKey("_format") && to != null && to.indexOf('.') > 0) {
                    map.put("_format", to.substring(to.lastIndexOf('.') + 1));
                }
                XDocService client  = new XDocService(server, xkey);
                OutputStream out;
                if (to != null) {
                    out = new FileOutputStream(to);
                } else {
                    out = System.out;
                }
                client.invoke(map, out);
                if (to != null) {
                    out.flush();
                    out.close();
                    System.out.println(">> " + to);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    private void invoke(Map<String, String> param, Object out) throws IOException {
        String xurl = this.url + (this.url.endsWith("/") ? "xdoc" : "/xdoc");
        HttpURLConnection httpConn = (HttpURLConnection) new URL(xurl).openConnection();
        httpConn.setDoOutput(true);
        OutputStream reqOut = httpConn.getOutputStream();
        reqOut.write(("&_key=").getBytes());
        reqOut.write(encode(this.key).getBytes());
        Iterator<String> it = param.keySet().iterator();
        String key;
        while (it.hasNext()) {
            key = it.next();
            reqOut.write(("&" + encode(key) + "=").getBytes());
            reqOut.write(encode(param.get(key)).getBytes());
        }
        reqOut.flush();
        reqOut.close();
        OutputStream os = null;
        if (out instanceof OutputStream) {
            os = (OutputStream) out;
        } else {
            try {
                Method method = out.getClass().getMethod("getOutputStream");
                os = (OutputStream) method.invoke(out);
                method = out.getClass().getMethod("setHeader", String.class, String.class);
                String[] headerNames = new String[] {"Content-Type", "Content-Disposition"};
                String headerValue;
                for (String headerName : headerNames) {
                    headerValue = httpConn.getHeaderField(headerName);
                    if (headerValue != null) {
                        method.invoke(out, headerName, headerValue);
                    }
                }
            } catch (Exception e) {
                throw new IOException(e);
            }
        }
        pipe(httpConn.getInputStream(), os);
    }
    private Object parse(byte[] data) throws IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(false);
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new ByteArrayInputStream(data));
            document.getDocumentElement().normalize();
            Element root = document.getDocumentElement();
            if (root.getAttribute("success").equals("true")) {
                Element result = (Element) root.getElementsByTagName("result").item(0);
                String dataType = result.getAttribute("dataType");
                if (dataType.equals("string")) {
                    return result.getTextContent();
                } else if (dataType.equals("map")) {
                    NodeList items = result.getElementsByTagName("value");
                    Map<String, String> map = new HashMap<String, String>();
                    Element value;
                    NamedNodeMap atts;
                    for (int i = 0; i < items.getLength(); i++) {
                        value = (Element) items.item(i);
                        atts = value.getAttributes();
                        for (int j = 0; j < atts.getLength(); j++) {
                            map.put(atts.item(j).getNodeName(), atts.item(j).getNodeValue());
                        }
                    }
                    return map;
                } else if (dataType.equals("rowset")) {
                    Map<String, String> fieldMap = new HashMap<String, String>();
                    String[] fields = result.getAttribute("fields").split(",");
                    String[] formerFields = fields;
                    if (result.hasAttribute("formerFields")) {
                        formerFields = csvSplit(result.getAttribute("formerFields"));
                    }
                    for (int j = 0; j < formerFields.length; j++) {
                        fieldMap.put(fields[j], formerFields[j]);
                    }
                    NodeList eleList = result.getElementsByTagName("row");
                    Element ele;
                    Map<String, String> map;
                    List<Map<String, String>> List = new ArrayList<Map<String, String>>();
                    for (int i = 0; i < eleList.getLength(); i++) {
                        ele = (Element) eleList.item(i);
                        map = new HashMap<String, String>();
                        List.add(map);
                        for (int j = 0; j < fields.length; j++) {
                            map.put(formerFields[j], ele.getAttribute(fields[j]));
                        }
                    }
                    return List;
                } else {
                    return "";
                }
            } else {
                throw new IOException(root.getElementsByTagName("error").item(0).getTextContent());
            }
        } catch (ParserConfigurationException e) {
            throw new IOException(e);
        } catch (SAXException e) {
            throw new IOException(e);
        }
    }
    private String invokeStringFunc(String func) throws IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("_func", func);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        invoke(params, out);
        return (String) parse(out.toByteArray());
    }
    private Map<String, String> checkParam(Map<String, Object> param) throws IOException {
        Map<String, String> map = new HashMap<String, String>();
        String key, value;
        Iterator<String> it = param.keySet().iterator();
        while (it.hasNext()) {
            key = it.next();
            value = toParamString(param.get(key));
            if (isXDocData(key, value)) {
                value = toDataURI(value);
            } else if (key.endsWith("@file")) {
                key = key.substring(0, key.length() - 5);
                value = toDataURI(value);
            }
            map.put(key, value);
        }
        return map;
    }
    private static String toParamString(Object obj) throws IOException {
        String str;
        if (obj == null) {
            str = "";
        } else if (obj.getClass().isPrimitive()
                || obj instanceof Boolean
                || obj instanceof Number
                || obj instanceof CharSequence) {
            str = obj.toString();
        } else if (obj instanceof Date) {
            str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) obj);
        } else if (obj instanceof File) {
            str = toDataURI(((File) obj).getAbsolutePath());
        } else if (obj instanceof InputStream) {
            str = toDataURI((InputStream) obj);
        } else {
            StringBuilder sb = new StringBuilder();
            Set<Object> chainSet = new HashSet<Object>();
            writeParamString(sb, obj, chainSet);
            str = sb.toString();
        }
        return str;
    }
    private static void writeParamString(StringBuilder sb, Object obj, Set<Object> set) throws IOException {
        if (obj == null) {
            sb.append("null");
        } else if (obj.getClass().isPrimitive()
                || obj instanceof Boolean
                || obj instanceof Number) {
            sb.append(toParamString(obj));
        } else if (obj instanceof CharSequence
                || obj instanceof Date) {
            jencode(toParamString(obj), sb);
        } else if (obj instanceof Collection) {
            sb.append("[");
            boolean b = false;
            Iterator<?> it = ((Collection<?>) obj).iterator();
            while (it.hasNext()) {
                if (b) sb.append(",");
                writeParamString(sb, it.next(), set);
                b = true;
            }
            sb.append("]");
        } else if (obj.getClass().isArray()) {
            sb.append("[");
            boolean b = false;
            int n = Array.getLength(obj);
            for (int i = 0; i < n; i++) {
                if (b) sb.append(",");
                writeParamString(sb, Array.get(obj, i), set);
                b = true;
            }
            sb.append("]");
        } else if (obj instanceof Map) {
            sb.append("{");
            Map<?, ?> map = (Map<?, ?>) obj;
            boolean b = false;
            Object key;
            Iterator<?> it = map.keySet().iterator();
            while (it.hasNext()) {
                if (b) sb.append(",");
                key = it.next();
                jencode(key.toString(), sb);
                sb.append(":");
                writeParamString(sb, map.get(key), set);
                b = true;
            }
            sb.append("}");
        } else {
            sb.append("{");
            if (!set.contains(obj) && obj.getClass() != Object.class && obj.getClass() != Class.class) {
                set.add(obj);
                try {
                    List<Method> getters = findGetters(obj);
                    boolean b = false;
                    for (Method method : getters) {
                        if (b) sb.append(",");
                        jencode(findGetterName(method), sb);
                        sb.append(":");
                        writeParamString(sb, method.invoke(obj, new Object[0]), set);
                        b = true;
                    }
                } catch (Exception e) {
                    throw new IOException(e);
                }
                set.remove(obj);
            }
            sb.append("}");
        }
    }
    private static List<Method> findGetters(Object obj) {
        List<Method> getters = new ArrayList<Method>();
        String name;
        for (Method method : obj.getClass().getMethods()) {
            name = method.getName();
            if (Modifier.isStatic(method.getModifiers())
                    || method.getReturnType().equals(Void.TYPE)
                    || method.getParameterTypes().length != 0
                    || method.getReturnType() == ClassLoader.class
                    ) {
                continue;
            }
            if (name.startsWith("get") && name.length() >= 4 && !name.equals("getClass")
                    || name.startsWith("is") && name.length() >= 3) {
                getters.add(method);
            }
        }
        return getters;
    }
    private static String findGetterName(Method method) {
        String name = method.getName();
        if (name.startsWith("get")) {
            name = name.substring(3);
        } else if (name.startsWith("is")) {
            name = name.substring(2);
        }
        if (name.length() > 1
                && Character.isUpperCase(name.charAt(1))
                && Character.isUpperCase(name.charAt(0))){
            return name;
        }
        char chars[] = name.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }
    private static void jencode(String str, StringBuilder sb) {
        sb.append("\"");
        char c;
        for (int i = 0; i < str.length(); i++) {
            c = str.charAt(i);
            if (c == '\\') {
                sb.append("\\\\");
            } else if (c == '/') {
                sb.append("\\/");
            } else if (c == '\n') {
                sb.append("\\n");
            } else if (c == '\r') {
                sb.append("\\r");
            } else if (c == '\t') {
                sb.append("\\t");
            } else if (c == '\'') {
                sb.append("\\\'");
            } else if (c == '\"') {
                sb.append("\\\"");
            } else {
                sb.append(c);
            }
        }
        sb.append("\"");
    }
    private static boolean isXDocData(String name, String value) {
        if (name.equals("_xdoc") || name.equals("_xdata")) {
            if (value.startsWith("./")
                    || value.startsWith("<")
                    || value.startsWith("{")
                    || value.startsWith("[")
                    || value.startsWith("data:")
                    || name.equals("_xdoc") && value.startsWith("text:")) {
                return false;
            } else {
                return true;
            }
        }
        return false;
    }
    private static String getFormat(String url) {
        String format = "xdoc";
        int pos = url.lastIndexOf(".");
        if (pos > 0) {
            format = url.substring(pos + 1).toLowerCase();
            if (format.equals("zip")) {
                url = url.substring(0, pos);
                pos = url.lastIndexOf(".");
                if (pos > 0) {
                    format = url.substring(pos + 1).toLowerCase() + ".zip";
                }
            }
        }
        return format;
    }
    private static String encode(Object str) {
        try {
            return URLEncoder.encode(String.valueOf(str), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return String.valueOf(str);
        }
    }
    private static String decode(String str) {
        try {
            return URLDecoder.decode(str, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return str;
        }
    }
    private static void pipe(InputStream in, OutputStream out) throws IOException {
        int len;
        byte[] buf = new byte[4096];
        while (true) {
            len = in.read(buf);
            if (len > 0) {
                out.write(buf, 0, len);
            } else {
                break;
            }
        }
        out.flush();
        out.close();
        in.close();
    }
    private static boolean isFile(String url) {
        int pos = url.indexOf(':');
        return pos < 0
                || pos == 1
                || (pos == 2 && url.charAt(0) == '/');
    }
    /**
     * URL結果轉換爲datauri
     * @param url http/ftp/file
     * @return
     * @throws IOException
     */
    public static String toDataURI(String url) throws IOException {
        return toDataURI(url, null);
    }
    /**
     * URL結果轉換爲datauri
     * @param url http/ftp/file
     * @param format 文件格式或mime-type
     * @return
     * @throws IOException
     */
    public static String toDataURI(String url, String format) throws IOException {
        if (url.length() > 0) {
            InputStream in = null;
            if (isFile(url) || url.startsWith("class://")) {
                if (format == null) {
                    int pos = url.lastIndexOf('.');
                    if (pos > 0) {
                        format = url.substring(pos + 1).toLowerCase();
                    }
                }
                if (url.startsWith("class://")) {
                    String cls = url.substring(8, url.indexOf("/", 8));
                    String path = url.substring(url.indexOf("/", 8) + 1);
                    try {
                        in = Class.forName(cls).getResourceAsStream(path);
                    } catch (Exception e) {
                        throw new IOException(e);
                    }
                } else {
                    in = new FileInputStream(url);
                }
            } else {
                URLConnection conn = new URL(url).openConnection();
                in = conn.getInputStream();
                if (format == null) {
                    format = conn.getContentType();
                }
            }
            return toDataURI(in, format);
        } else {
            return "";
        }
    }
    /**
     * 數據流轉換爲datauri
     * @param in
     * @return
     * @throws IOException
     */
    public static String toDataURI(InputStream in) throws IOException {
        return toDataURI(in, null);
    }
    /**
     * 數據流轉換爲datauri
     * @param in
     * @param format 文件格式或mime-type
     * @return
     * @throws IOException
     */
    public static String toDataURI(InputStream in, String format) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        pipe(in, out);
        if (format != null) {
            if (format.indexOf('/') < 0) {
                if (format.equals("jpg")) {
                    format = "jpeg";
                } else if (format.equals("htm")) {
                    format = "html";
                }
                if (format.equals("png") || format.equals("jpeg") || format.equals("gif")) {
                    format = "image/" + format;
                } else if (format.equals("html") || format.equals("xml")) {
                    format = "text/" + format;
                } else {
                    format = "application/" + format;
                }
            }
        } else {
            format = "application/octet-stream";
        }
        StringBuffer sb = new StringBuffer();
        sb.append("data:").append(format).append(";base64,");
        sb.append(toBase64(out.toByteArray()));
        return sb.toString();
    }
    private static String toBase64(final byte[] data) {
        final char[] out = new char[((data.length + 2) / 3) * 4];
        for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
            boolean quad = false;
            boolean trip = false;

            int val = (0xFF & data[i]);
            val <<= 8;
            if ((i + 1) < data.length) {
                val |= (0xFF & data[i + 1]);
                trip = true;
            }
            val <<= 8;
            if ((i + 2) < data.length) {
                val |= (0xFF & data[i + 2]);
                quad = true;
            }
            out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
            val >>= 6;
            out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
            val >>= 6;
            out[index + 1] = alphabet[val & 0x3F];
            val >>= 6;
            out[index + 0] = alphabet[val & 0x3F];
        }
        return new String(out);
    }
    private static char[] alphabet =
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
    private static byte[] codes = new byte[256];
    static {
        for (int i = 0; i < 256; i++) {
            codes[i] = -1;
        }
        for (int i = 'A'; i <= 'Z'; i++) {
            codes[i] = (byte) (i - 'A');
        }
        for (int i = 'a'; i <= 'z'; i++) {
            codes[i] = (byte) (26 + i - 'a');
        }
        for (int i = '0'; i <= '9'; i++) {
            codes[i] = (byte) (52 + i - '0');
        }
        codes['+'] = 62;
        codes['/'] = 63;
    }
    private static String[] csvSplit(String str) {
        List<List<String>> list = csvList(str);
        if (list.size() > 0) {
            List<String> cols = (List<String>) list.get(0);
            String[] strs = new String[cols.size()];
            for (int i = 0; i < strs.length; i++) {
                strs[i] = cols.get(i);
            }
            return strs;
        } else {
            return new String[0];
        }
    }
    private static List<List<String>> csvList(String txt) {
        if (txt.length() > 0) {
            ArrayList<List<String>> rows = new ArrayList<List<String>>();
            ArrayList<String> cols = new ArrayList<String>();
            rows.add(cols);
            char c;
            boolean strBegin = false;
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < txt.length(); i++) {
                c = txt.charAt(i);
                if (strBegin) {
                    if (c == '"') {
                        if (i + 1 < txt.length()) {
                            if (txt.charAt(i + 1) == '"') {
                                sb.append(c);
                                i++;
                            } else {
                                strBegin = false;
                            }
                        } else {
                            strBegin = false;
                        }
                    } else {
                        sb.append(c);
                    }
                } else {
                    if (c == ',') {
                        cols.add(sb.toString());
                        sb.setLength(0);
                    } else if (c == '\n') {
                        cols.add(sb.toString());
                        sb.setLength(0);
                        cols = new ArrayList<String>();
                        rows.add(cols);
                    } else if (c == '"') {
                        strBegin = true;
                    } else if (c != '\r') {
                        sb.append(c);
                    }
                }
            }
            if (sb.length() > 0) {
                cols.add(sb.toString());
            }
            return rows;
        } else {
            return new ArrayList<List<String>>();
        }
    }
    /**
     * XDOC註解
     * @author XDOC
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface XDoc {
        /**
         * xdoc
         * @return
         */
        public String value() default "";
    }
    /**
     * XDOC參數註解
     * @author XDOC
     */
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface XParam {
        /**
         * 參數名稱
         * @return
         */
        public String value() default "";
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章