Android中文檔預(yù)覽功能的實(shí)現(xiàn)思路及問(wèn)題

Andriod中的文檔在線查看功能嗓袱,類似于網(wǎng)易郵箱大師中的附件預(yù)覽功能籍救,要求在app內(nèi)直接打開(kāi)office文檔、pdf文檔等渠抹。

思路一:后臺(tái)統(tǒng)一轉(zhuǎn)換文檔格式蝙昙,安卓端只預(yù)覽一種格式文檔。

  • 在后臺(tái)將office(Word梧却、Excle奇颠、PPT)文檔轉(zhuǎn)換為pdf文檔,在安卓端預(yù)覽的時(shí)候篮幢,其實(shí)是從后臺(tái)先把pdf文檔下載到手機(jī)上大刊,再去讀取为迈。

  • 后臺(tái):openoffice + jodconverter將office文檔轉(zhuǎn)換為pdf格式三椿。

    集成難度不大,網(wǎng)上教程非常多葫辐,需要在服務(wù)器上安裝openoffice搜锰,轉(zhuǎn)換速度很慢(頁(yè)數(shù)多特別明顯,頁(yè)數(shù)少的話速度在可以接受的范圍之內(nèi)耿战,轉(zhuǎn)換速度與文檔大小關(guān)系不大蛋叼,主要是文檔頁(yè)數(shù))。

  • 安卓端使用AndroidPdfViewer第三方庫(kù)顯示pdf文檔。

    就是使用第三方庫(kù)狈涮,也很簡(jiǎn)單狐胎。

思路二:在安卓端完成文檔轉(zhuǎn)換

  • 使用Apache的Poi組件,但是由于ppt在轉(zhuǎn)換過(guò)程中需要用到j(luò)ava的awt歌馍,所以無(wú)法實(shí)現(xiàn)ppt的轉(zhuǎn)換握巢,也就是說(shuō)只能實(shí)現(xiàn)word、excle的轉(zhuǎn)換松却。如果項(xiàng)目中只是有轉(zhuǎn)換word或者excle的需求暴浦,可以采用Poi。
  • 具體是:使用Poi將doc晓锻、docx歌焦、xls、xlsx文檔轉(zhuǎn)換為html砚哆,再使用webview加載本地html独撇。
  • 這里要注意的是,Poi的jar包的導(dǎo)入躁锁。如果去apache的poi官網(wǎng)查看各組件的功能券勺,以及要導(dǎo)入的jar包,但是網(wǎng)上的代碼一般都是org.apache.poi.xwpf.converter.xhtml
    這個(gè)庫(kù)的灿里。等你導(dǎo)入了這個(gè)庫(kù)关炼,又自己從官網(wǎng)上下載了poi、poi-ooxml等jar包引入后匣吊,很可能會(huì)導(dǎo)致編譯出錯(cuò)儒拂,提示有重復(fù)文件。這是由于導(dǎo)入的jar包的版本不一致導(dǎo)致的色鸳。正確的導(dǎo)入方式可以參考下面的:
    這個(gè)會(huì)自動(dòng)把關(guān)聯(lián)的jar包引入社痛,從maven倉(cāng)庫(kù)可以看到這個(gè)jar的依賴,以及依賴的依賴命雀,
    總之很多蒜哀,可以在project視圖中External Libraries來(lái)查看這個(gè)庫(kù)文件到底包含了哪些jar包。
    compile 'fr.opensagres.xdocreport:org.apache.poi.xwpf.converter.xhtml:1.0.6'
  ---------------------------------------------------------------------------------------------------
    這個(gè)主要是doc的轉(zhuǎn)換用到的吏砂,可以不引入撵儿,網(wǎng)上也有很多轉(zhuǎn)換方法沒(méi)有用到這個(gè)庫(kù)
    //compile 'fr.opensagres.xdocreport:fr.opensagres.xdocreport.document:1.0.6'
  --------------------------------------------------------------------------------------------------- 
    這個(gè)庫(kù)文件的版本至關(guān)重要,因?yàn)?..xhtml:1.0.6中依賴的poi等jar的版本就是3.10-FINAL狐血,
    所以這里必須也是3.10-FINAL淀歇,不然編譯肯定不會(huì)通過(guò)。
    compile 'org.apache.poi:poi-scratchpad:3.10-FINAL'

總之匈织,如果你在apache.poi官網(wǎng)上看各個(gè)組件之間的依賴關(guān)系有些困難浪默,可以去maven看牡直。
  • 除了引入庫(kù)文件以外,還需要在app的gradle文件中添加如下語(yǔ)句:
  defaultConfig {
      ...
      multiDexEnabled true
      ...
  }
  packagingOptions { 
        ...
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
  dexOptions {
        javaMaxHeapSize "3g"
        jumboMode = true
        preDexLibraries = false
    }
    lintOptions {
        abortOnError false
    }
    project.tasks.withType(com.android.build.gradle.tasks.Dex) {
        additionalParameters = ['--core-library']
    }

思路三:其他

  • 參考附件在線預(yù)覽控件實(shí)現(xiàn)的市場(chǎng)調(diào)研

  • POI由于預(yù)覽效果不是很好纳决,不建議使用(安卓無(wú)法轉(zhuǎn)換ppt與pptx)

  • Flashpaper缺少后續(xù)支持碰逸,不建議使用(后臺(tái),與安卓無(wú)關(guān))

  • 第三方付費(fèi)產(chǎn)品中阔加,Office Web 365

    完全依賴于第三方云服務(wù)花竞,在安全性、靈活性掸哑、穩(wěn)定性為驗(yàn)證约急,不建議使用

  • 科瀚的SOAOffice和卓正軟件的pageoffice需要瀏覽器Activex插件的支持,對(duì)用戶不是很友好苗分,不建議試用(后臺(tái)厌蔽,與安卓無(wú)關(guān))

  • OpenOffice的預(yù)覽效果稍差,但集成方便摔癣;

  • Office Web Apps預(yù)覽效果最佳奴饮,釘釘、126等也采用此方式择浊,但估計(jì)集成難度稍大戴卜,另外釘釘?shù)念A(yù)覽偶爾也出現(xiàn)不穩(wěn)定的情況;

  • 永中office的預(yù)覽效果和集成難度比較平衡琢岩,但需付費(fèi)投剥。

  • 總之,除非需求必須担孔,否則這種功能還是不要實(shí)現(xiàn)江锨,因?yàn)殡y度很大,耗時(shí)費(fèi)力糕篇,一般情況下交給系統(tǒng)去打開(kāi)就行了啄育。當(dāng)然,主要功能是文檔閱讀的app除外拌消。

一些代碼參考

說(shuō)明:大部分是從網(wǎng)上找的挑豌,僅供參考,功能沒(méi)問(wèn)題墩崩,但很多細(xì)節(jié)有待完善氓英。

package com.ght.loginapp.utilities;

import org.apache.poi.hssf.converter.ExcelToHtmlConverter;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.converter.core.FileImageExtractor;
import org.apache.poi.xwpf.converter.core.FileURIResolver;
import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter;
import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.w3c.dom.Document;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;


import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.util.Map;


import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;


/**
 * 2016/9/12 0012,由 yuezc 創(chuàng)建 .
 * <p/>
 * 功能描述:
 * <p/>
 * 說(shuō)明:
 * ---------------------------
 * 修改時(shí)間:
 * 修改說(shuō)明:
 * 修改人:
 * <p/>
 * POIFS
 * POIFS是該項(xiàng)目的最古老泰鸡,最穩(wěn)定的一部分债蓝。.這是格式化OLE 2復(fù)合文檔為純Java的接口壳鹤。 它同時(shí)支持讀寫(xiě)功能盛龄。所有的組件,最終都依賴于它的定義
 * <p/>
 * HSSF 和 XSSF
 * HSSF: MS-Excel 97-2003(.xls),基于BIFF8格式的JAVA接口余舶。
 * XSSF:MS-Excel 2007+(.xlsx),基于OOXML格式的JAVA接口啊鸭。
 * <p/>
 * HWPF 和XWPF
 * HWPF: MS-Word 97-2003(.doc),基于BIFF8格式的JAVA接口匿值。只支持.doc文件簡(jiǎn)單的操作赠制,讀寫(xiě)能力有限。本API為POI項(xiàng)目早期開(kāi)發(fā)挟憔,很不幸的 是主要負(fù)責(zé)HWPF模塊開(kāi)發(fā)的工程師-“Ryan Ackley”已經(jīng)離開(kāi)Apache組織钟些,現(xiàn)在該模塊沒(méi)有人維護(hù)、更新绊谭、完善政恍。
 * XWPF:MS-Word 2007+(.docx),基于OOXML格式的JAVA接口。較HWPF功能完善达传。
 */
public class DocumentFormatConvertUtils {

    /**
     * doc文檔轉(zhuǎn)成html格式
     */
    public static void doc2html(String docPath, final String docName, String htmlName, String htmlPath) {

        HWPFDocument wordDocument = null;
        try {
            wordDocument = new HWPFDocument(new FileInputStream(docPath + docName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        WordToHtmlConverter wordToHtmlConverter = null;
        try {
            wordToHtmlConverter = new WordToHtmlConverter(
                    DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }

        //設(shè)置圖片路徑
        wordToHtmlConverter.setPicturesManager(new PicturesManager() {
            public String savePicture(byte[] content,
                                      PictureType pictureType, String suggestedName,
                                      float widthInches, float heightInches) {
                String name = docName.substring(0, docName.indexOf("\\."));
                return name + "/" + suggestedName;
            }
        });

        //保存圖片
        List<Picture> pics = wordDocument.getPicturesTable().getAllPictures();
        if (pics != null) {
            for (int i = 0; i < pics.size(); i++) {
                Picture pic = (Picture) pics.get(i);
                System.out.println(pic.suggestFullFileName());
                try {
                    String name = docName.substring(0, docName.indexOf("\\."));
                    pic.writeImageContent(new FileOutputStream(htmlPath + name + "/"
                            + pic.suggestFullFileName()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        wordToHtmlConverter.processDocument(wordDocument);
        Document htmlDocument = wordToHtmlConverter.getDocument();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        DOMSource domSource = new DOMSource(htmlDocument);
        StreamResult streamResult = new StreamResult(out);

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer serializer = null;
        try {
            serializer = tf.newTransformer();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        }
        serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        serializer.setOutputProperty(OutputKeys.METHOD, "html");
        try {
            serializer.transform(domSource, streamResult);
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        try {
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //保存html文件
        writeFile(new String(out.toByteArray()), htmlPath + htmlName);
    }

    /**
     * docx文檔轉(zhuǎn)成html格式
     */
    public static void docx2html(String docxPath, String docxName, String htmlName, String htmlPath) {

        try {
            final String file = docxPath + docxName;
            File f = new File(file);
            if (!f.exists()) {
                System.out.println("Sorry File does not Exists!");
            } else {
                if (f.getName().endsWith(".docx") || f.getName().endsWith(".DOCX")) {

                    // 1) 加載word文檔生成 XWPFDocument對(duì)象
                    InputStream in = new FileInputStream(f);
                    XWPFDocument document = new XWPFDocument(in);

                    // 2) 解析 XHTML配置 (這里設(shè)置IURIResolver來(lái)設(shè)置圖片存放的目錄)
                    File imageFolderFile = new File(docxPath);
                    XHTMLOptions options = XHTMLOptions.create().URIResolver(new FileURIResolver(imageFolderFile));
                    options.setExtractor(new FileImageExtractor(imageFolderFile));
                    options.setIgnoreStylesIfUnused(false);
                    options.setFragment(true);

                    // 3) 將 XWPFDocument轉(zhuǎn)換成XHTML
                    OutputStream out = new FileOutputStream(new File(htmlPath + htmlName));
                    XHTMLConverter.getInstance().convert(document, out, options);
                } else {
                    System.out.println("Enter only MS Office 2007+ files");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * xls文檔轉(zhuǎn)成html格式
     */
    public static void xls2html(String xlsPath, String xlsName, String htmlName, String htmlPath) {

        try {
            InputStream input = new FileInputStream(xlsPath + xlsName);
            HSSFWorkbook excelBook = new HSSFWorkbook(input);
            ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
            excelToHtmlConverter.processWorkbook(excelBook);
            List pics = excelBook.getAllPictures();
            if (pics != null) {
                for (int i = 0; i < pics.size(); i++) {
                    Picture pic = (Picture) pics.get(i);
                    try {
                        pic.writeImageContent(new FileOutputStream(xlsName.substring(0, xlsName.indexOf(".")) + pic.suggestFullFileName()));
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
            Document htmlDocument = excelToHtmlConverter.getDocument();
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            DOMSource domSource = new DOMSource(htmlDocument);
            StreamResult streamResult = new StreamResult(outStream);
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer serializer = tf.newTransformer();
            serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            serializer.setOutputProperty(OutputKeys.METHOD, "html");
            serializer.transform(domSource, streamResult);
            outStream.close();
            //保存html文件
            writeFile(new String(outStream.toByteArray()), htmlPath + htmlName);
        } catch (Exception e) {

        }
    }

    /**
     * xlsx文檔轉(zhuǎn)成html格式
     */
    public static void xlsx2html(String xlsxPath, String xlsxName, String htmlName, String htmlPath) {
        writeFile(readExcelToHtml(xlsxPath + xlsxName, true), htmlPath + htmlName);
    }

    public static void ppt2html(String pptPath, String pptName, String htmlName, String htmlPath) {
        //抱歉篙耗,沒(méi)有實(shí)現(xiàn)
    }

    public static void pptx2html(String pptxPath, String pptxName, String htmlName, String htmlPath) {
        //抱歉,沒(méi)有實(shí)現(xiàn)
    }


---------------------------------------
    /**
     * 將html文件保存到sd卡
     */
    public static void writeFile(String content, String path) {
        FileOutputStream fos = null;
        BufferedWriter bw = null;
        try {
            File file = new File(path);
            if (!file.exists()) {
                file.createNewFile();
            }
            fos = new FileOutputStream(file);
            bw = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"));
            bw.write(content);
        } catch (FileNotFoundException fnfe) {
            fnfe.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            try {
                if (bw != null)
                    bw.close();
                if (fos != null)
                    fos.close();
            } catch (IOException ie) {
            }
        }
    }

    /**
     * @param filePath    文件的路徑
     * @param isWithStyle 是否需要表格樣式 包含 字體 顏色 邊框 對(duì)齊方式
     * @return <table>
     * ...
     * </table>
     * 字符串
     */
    public static String readExcelToHtml(String filePath, boolean isWithStyle) {

        InputStream is = null;
        String htmlExcel = null;
        try {
            File sourcefile = new File(filePath);
            is = new FileInputStream(sourcefile);
            Workbook wb = WorkbookFactory.create(is);
            if (wb instanceof XSSFWorkbook) {
                XSSFWorkbook xWb = (XSSFWorkbook) wb;
                htmlExcel = getExcelInfo(xWb, isWithStyle);
            } else if (wb instanceof HSSFWorkbook) {
                HSSFWorkbook hWb = (HSSFWorkbook) wb;
                htmlExcel = getExcelInfo(hWb, isWithStyle);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return htmlExcel;
    }


    public static String getExcelInfo(Workbook wb, boolean isWithStyle) {

        StringBuffer sb = new StringBuffer();
        Sheet sheet = wb.getSheetAt(0);// 獲取第一個(gè)Sheet的內(nèi)容
        int lastRowNum = sheet.getLastRowNum();
        Map<String, String> map[] = getRowSpanColSpanMap(sheet);
        sb.append("<table style='border-collapse:collapse;' width='100%'>");
        Row row = null; // 兼容
        Cell cell = null; // 兼容
        for (int rowNum = sheet.getFirstRowNum(); rowNum <= lastRowNum; rowNum++) {
            row = sheet.getRow(rowNum);
            if (row == null) {
                sb.append("<tr><td >  </td></tr>");
                continue;
            }
            sb.append("<tr>");
            int lastColNum = row.getLastCellNum();
            for (int colNum = 0; colNum < lastColNum; colNum++) {
                cell = row.getCell(colNum);
                if (cell == null) { // 特殊情況 空白的單元格會(huì)返回null
                    sb.append("<td> </td>");
                    continue;
                }
                String stringValue = getCellValue(cell);
                if (map[0].containsKey(rowNum + "," + colNum)) {
                    String pointString = map[0].get(rowNum + "," + colNum);
                    map[0].remove(rowNum + "," + colNum);
                    int bottomeRow = Integer.valueOf(pointString.split(",")[0]);
                    int bottomeCol = Integer.valueOf(pointString.split(",")[1]);
                    int rowSpan = bottomeRow - rowNum + 1;
                    int colSpan = bottomeCol - colNum + 1;
                    sb.append("<td rowspan= '" + rowSpan + "' colspan= '" + colSpan + "' ");
                } else if (map[1].containsKey(rowNum + "," + colNum)) {
                    map[1].remove(rowNum + "," + colNum);
                    continue;
                } else {
                    sb.append("<td ");
                }
                // 判斷是否需要樣式
                if (isWithStyle) {
                    dealExcelStyle(wb, sheet, cell, sb);// 處理單元格樣式
                }
                sb.append(">");
                if (stringValue == null || "".equals(stringValue.trim())) {
                    sb.append("   ");
                } else {
                    // 將ascii碼為160的空格轉(zhuǎn)換為html下的空格( )
                    sb.append(stringValue.replace(String.valueOf((char) 160), " "));
                }
                sb.append("</td>");
            }
            sb.append("</tr>");
        }

        sb.append("</table>");
        return sb.toString();


    }

    private static Map<String, String>[] getRowSpanColSpanMap(Sheet sheet) {
        Map<String, String> map0 = new HashMap<String, String>();
        Map<String, String> map1 = new HashMap<String, String>();
        int mergedNum = sheet.getNumMergedRegions();
        CellRangeAddress range = null;
        for (int i = 0; i < mergedNum; i++) {
            range = sheet.getMergedRegion(i);
            int topRow = range.getFirstRow();
            int topCol = range.getFirstColumn();
            int bottomRow = range.getLastRow();
            int bottomCol = range.getLastColumn();
            map0.put(topRow + "," + topCol, bottomRow + "," + bottomCol);
            // System.out.println(topRow + "," + topCol + "," + bottomRow + ","
            // + bottomCol);
            int tempRow = topRow;
            while (tempRow <= bottomRow) {
                int tempCol = topCol;
                while (tempCol <= bottomCol) {
                    map1.put(tempRow + "," + tempCol, "");
                    tempCol++;
                }
                tempRow++;
            }
            map1.remove(topRow + "," + topCol);
        }
        Map[] map = {map0, map1};
        return map;
    }

    /**
     * 獲取表格單元格Cell內(nèi)容
     *
     * @param cell
     * @return
     */
    private static String getCellValue(Cell cell) {
        String result = new String();
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_NUMERIC:// 數(shù)字類型
                if (HSSFDateUtil.isCellDateFormatted(cell)) {// 處理日期格式宪赶、時(shí)間格式
                    SimpleDateFormat sdf = null;
                    if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
                        sdf = new SimpleDateFormat("HH:mm");
                    } else {// 日期
                        sdf = new SimpleDateFormat("yyyy-MM-dd");
                    }
                    Date date = cell.getDateCellValue();
                    result = sdf.format(date);
                } else if (cell.getCellStyle().getDataFormat() == 58) {
                    // 處理自定義日期格式:m月d日(通過(guò)判斷單元格的格式id解決宗弯,id的值是58)
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    double value = cell.getNumericCellValue();
                    Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
                    result = sdf.format(date);
                } else {
                    double value = cell.getNumericCellValue();
                    CellStyle style = cell.getCellStyle();
                    DecimalFormat format = new DecimalFormat();
                    String temp = style.getDataFormatString();
                    // 單元格設(shè)置成常規(guī)
                    if (temp.equals("General")) {
                        format.applyPattern("#");
                    }
                    result = format.format(value);
                }
                break;
            case Cell.CELL_TYPE_STRING:// String類型
                result = cell.getRichStringCellValue().toString();
                break;
            case Cell.CELL_TYPE_BLANK:
                result = "";
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    /**
     * 處理表格樣式
     *
     * @param wb
     * @param sheet
     * @param cell
     * @param sb
     */
    private static void dealExcelStyle(Workbook wb, Sheet sheet, Cell cell, StringBuffer sb) {

        CellStyle cellStyle = cell.getCellStyle();
        if (cellStyle != null) {
            short alignment = cellStyle.getAlignment();
            sb.append("align='" + convertAlignToHtml(alignment) + "' ");// 單元格內(nèi)容的水平對(duì)齊方式
            short verticalAlignment = cellStyle.getVerticalAlignment();
            sb.append("valign='" + convertVerticalAlignToHtml(verticalAlignment) + "' ");// 單元格中內(nèi)容的垂直排列方式
            if (wb instanceof XSSFWorkbook) {
                XSSFFont xf = ((XSSFCellStyle) cellStyle).getFont();
                short boldWeight = xf.getBoldweight();
                sb.append("style='");
                sb.append("font-weight:" + boldWeight + ";"); // 字體加粗
                sb.append("font-size: " + xf.getFontHeight() / 2 + "%;"); // 字體大小
                int columnWidth = sheet.getColumnWidth(cell.getColumnIndex());
                sb.append("width:" + columnWidth + "px;");
                XSSFColor xc = xf.getXSSFColor();
                if (xc != null && !"".equals(xc)) {
                    sb.append("color:#" + xc.getARGBHex().substring(2) + ";"); // 字體顏色
                }

                XSSFColor bgColor = (XSSFColor) cellStyle.getFillForegroundColorColor();
                // System.out.println("************************************");
                // System.out.println("BackgroundColorColor:
                // "+cellStyle.getFillBackgroundColorColor());
                // System.out.println("ForegroundColor:
                // "+cellStyle.getFillForegroundColor());//0
                // System.out.println("BackgroundColorColor:
                // "+cellStyle.getFillBackgroundColorColor());
                // System.out.println("ForegroundColorColor:
                // "+cellStyle.getFillForegroundColorColor());
                // String bgColorStr = bgColor.getARGBHex();
                // System.out.println("bgColorStr: "+bgColorStr);
                if (bgColor != null && !"".equals(bgColor)) {
                    sb.append("background-color:#" + bgColor.getARGBHex().substring(2) + ";"); // 背景顏色
                }
                sb.append(getBorderStyle(0, cellStyle.getBorderTop(),
                        ((XSSFCellStyle) cellStyle).getTopBorderXSSFColor()));
                sb.append(getBorderStyle(1, cellStyle.getBorderRight(),
                        ((XSSFCellStyle) cellStyle).getRightBorderXSSFColor()));
                sb.append(getBorderStyle(2, cellStyle.getBorderBottom(),
                        ((XSSFCellStyle) cellStyle).getBottomBorderXSSFColor()));
                sb.append(getBorderStyle(3, cellStyle.getBorderLeft(),
                        ((XSSFCellStyle) cellStyle).getLeftBorderXSSFColor()));

            } else if (wb instanceof HSSFWorkbook) {

                HSSFFont hf = ((HSSFCellStyle) cellStyle).getFont(wb);
                short boldWeight = hf.getBoldweight();
                short fontColor = hf.getColor();
                sb.append("style='");
                HSSFPalette palette = ((HSSFWorkbook) wb).getCustomPalette(); // 類HSSFPalette用于求的顏色的國(guó)際標(biāo)準(zhǔn)形式
                HSSFColor hc = palette.getColor(fontColor);
                sb.append("font-weight:" + boldWeight + ";"); // 字體加粗
                sb.append("font-size: " + hf.getFontHeight() / 2 + "%;"); // 字體大小
                String fontColorStr = convertToStardColor(hc);
                if (fontColorStr != null && !"".equals(fontColorStr.trim())) {
                    sb.append("color:" + fontColorStr + ";"); // 字體顏色
                }
                int columnWidth = sheet.getColumnWidth(cell.getColumnIndex());
                sb.append("width:" + columnWidth + "px;");
                short bgColor = cellStyle.getFillForegroundColor();
                hc = palette.getColor(bgColor);
                String bgColorStr = convertToStardColor(hc);
                if (bgColorStr != null && !"".equals(bgColorStr.trim())) {
                    sb.append("background-color:" + bgColorStr + ";"); // 背景顏色
                }
                sb.append(getBorderStyle(palette, 0, cellStyle.getBorderTop(), cellStyle.getTopBorderColor()));
                sb.append(getBorderStyle(palette, 1, cellStyle.getBorderRight(), cellStyle.getRightBorderColor()));
                sb.append(getBorderStyle(palette, 3, cellStyle.getBorderLeft(), cellStyle.getLeftBorderColor()));
                sb.append(getBorderStyle(palette, 2, cellStyle.getBorderBottom(), cellStyle.getBottomBorderColor()));
            }

            sb.append("' ");
        }
    }

    /**
     * 單元格內(nèi)容的水平對(duì)齊方式
     *
     * @param alignment
     * @return
     */
    private static String convertAlignToHtml(short alignment) {

        String align = "left";
        switch (alignment) {
            case CellStyle.ALIGN_LEFT:
                align = "left";
                break;
            case CellStyle.ALIGN_CENTER:
                align = "center";
                break;
            case CellStyle.ALIGN_RIGHT:
                align = "right";
                break;
            default:
                break;
        }
        return align;
    }

    /**
     * 單元格中內(nèi)容的垂直排列方式
     *
     * @param verticalAlignment
     * @return
     */
    private static String convertVerticalAlignToHtml(short verticalAlignment) {

        String valign = "middle";
        switch (verticalAlignment) {
            case CellStyle.VERTICAL_BOTTOM:
                valign = "bottom";
                break;
            case CellStyle.VERTICAL_CENTER:
                valign = "center";
                break;
            case CellStyle.VERTICAL_TOP:
                valign = "top";
                break;
            default:
                break;
        }
        return valign;
    }

    private static String convertToStardColor(HSSFColor hc) {

        StringBuffer sb = new StringBuffer("");
        if (hc != null) {
            if (HSSFColor.AUTOMATIC.index == hc.getIndex()) {
                return null;
            }
            sb.append("#");
            for (int i = 0; i < hc.getTriplet().length; i++) {
                sb.append(fillWithZero(Integer.toHexString(hc.getTriplet()[i])));
            }
        }

        return sb.toString();
    }

    private static String fillWithZero(String str) {
        if (str != null && str.length() < 2) {
            return "0" + str;
        }
        return str;
    }

    static String[] bordesr = {"border-top:", "border-right:", "border-bottom:", "border-left:"};
    static String[] borderStyles = {"solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ",
            "solid ", "solid", "solid", "solid", "solid", "solid"};

    private static String getBorderStyle(HSSFPalette palette, int b, short s, short t) {
        if (s == 0)
            return bordesr[b] + borderStyles[s] + "#d0d7e5 1px;";
        String borderColorStr = convertToStardColor(palette.getColor(t));
        borderColorStr = borderColorStr == null || borderColorStr.length() < 1 ? "#000000" : borderColorStr;
        return bordesr[b] + borderStyles[s] + borderColorStr + " 1px;";

    }

    private static String getBorderStyle(int b, short s, XSSFColor xc) {

        if (s == 0)
            return bordesr[b] + borderStyles[s] + "#d0d7e5 1px;";
        if (xc != null && !"".equals(xc)) {
            String borderColorStr = xc.getARGBHex();// t.getARGBHex();
            borderColorStr = borderColorStr == null || borderColorStr.length() < 1 ? "#000000"
                    : borderColorStr.substring(2);
            return bordesr[b] + borderStyles[s] + borderColorStr + " 1px;";
        }

        return "";
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市搂妻,隨后出現(xiàn)的幾起案子蒙保,更是在濱河造成了極大的恐慌,老刑警劉巖欲主,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件追他,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡岛蚤,警方通過(guò)查閱死者的電腦和手機(jī)邑狸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)涤妒,“玉大人单雾,你說(shuō)我怎么就攤上這事∷希” “怎么了硅堆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)贿讹。 經(jīng)常有香客問(wèn)我渐逃,道長(zhǎng),這世上最難降的妖魔是什么民褂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任茄菊,我火速辦了婚禮疯潭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘面殖。我一直安慰自己竖哩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布脊僚。 她就那樣靜靜地躺著相叁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辽幌。 梳的紋絲不亂的頭發(fā)上增淹,一...
    開(kāi)封第一講書(shū)人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音乌企,去河邊找鬼埠通。 笑死,一個(gè)胖子當(dāng)著我的面吹牛逛犹,可吹牛的內(nèi)容都是我干的凰棉。 我是一名探鬼主播届惋,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼悠汽,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贩据!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起码撰,我...
    開(kāi)封第一講書(shū)人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤渗柿,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后脖岛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體朵栖,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年柴梆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了陨溅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绍在,死狀恐怖门扇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情偿渡,我是刑警寧澤臼寄,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站溜宽,受9級(jí)特大地震影響吉拳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜适揉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一留攒、第九天 我趴在偏房一處隱蔽的房頂上張望煤惩。 院中可真熱鬧,春花似錦稼跳、人聲如沸盟庞。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至票彪,卻和暖如春红淡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背降铸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工在旱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人推掸。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓桶蝎,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親谅畅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子登渣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容