ReportAnywhere Excel文檔導出程序

Yangcl 11年前發布 | 69K 次閱讀 Excel POI OA PDM Office文檔處理 Team center JSON

ReportAnywhere Excel文檔導出程序

       ReportAnywhere 是我自己寫的一個小程序,這個程序致力于解決OA、MIS、網站、大型集成系統、PDM、Team center、SAP和物聯網系統的Excel文檔導出問題。在信息化的過程中,不可避免的會遇到客戶要求“導出Excel文檔”這一類的要求。但是由于每一個Excel的格式、樣式有諸多不同、繁瑣等問題,給程序員造成了很多煩惱。處于上述因素考慮,我編寫的程序可能在某一個特殊的Excel格式中還不適合,可能會報錯。但針對大多數情況,這個程序是完全兼容的。您必要時可以根據自己的需求進行特殊的處理和改進。但請您切記:不要用于任何嘗試收費的、商業的用途,本程序最終所有權歸作者本人所有。
       當前用于 
通過java操作excel表格的工具類庫 這一目的手段有兩種:1 jxl,一位日本程序員的開源類庫。缺點是不能夠支持Office 2003以上版本,對圖片識別和處理能力僅限于PNG格式。2 POI, Apache POI是Apache軟件基金會的開放源碼函式庫,POI提供API給Java程序對Microsoft Office格式檔案讀和寫的功能。功能強悍、性能穩定。相對與jxl來講,幾乎占盡各方面優勢。 ReportAnywhere 使用POI作為操作Excel的工具。
       

ReportAnywhere設計思路

          qq截圖20130201214829.png

          ReportBuilder

          這個類提供了向Excel中單個單元格寫入的方法:writeInTemplate(),包括寫入字符串和寫入圖片兩種。加載模板的方法:loadTemplate() 。保存模版中的內容到一個新文件中的方法:SaveTemplate()。檢查是否存在多sheet頁情況的方法:checkAndAddSheet()。

          ReportManager

          這個類提供了加載Xml配置文件的方法:loadXmlMapping()。4個存儲Xml配置文件中信息的私有方法:List<GenericField> head(),Map<String,List<BodyField>> body(),List<GenericField> foot(),List<ImageField> image()。這4個方法以實體類作為存儲的依據。處理外部系統數據流的方法:process(Map map)、processData(Stri
ng 
 jsonString)。 一個公開的接口:doReport(String excelURL,String xmlURL,String jsonString,String saveURL)和
一個專門用來處理 Json 字符串循環套嵌的靜態類:NaturalDeserializer。

        Entity 

          Entity提供了對應的實體。entity.BodyField:專門針對Xml配置文件的Body節點部分設計。entity.genericField
:針對Xml配置文件的Head節點、Foot節點設計。entity.ImageField:針對Xml配置文件的Image節點設計。以他們去存儲各自對應的節點內容。

          config-reportMapping.xml

          整個程序最精彩的部分。在這里體現了模塊化設計的思想、SOA的思想。在不改變程序源代碼、不進行程序再次編譯的基礎上,通過配置外部文件去實現用戶的功能。最大限度的實現了代碼重用、提高系統運行效率。針對一些不入流的程序員將一個Team Center的報表程序寫到了13000行+的代碼量,到處出現重復的代碼,讓別人維護起來陣陣作嘔,真心覺得他可以回家看孩子了,開發不適合他。
          在一個大型的系統中可能會出現要導出很多Excel文件的情況。在這種情況下你還要為每一個Excel文件的導出去寫一個類嗎?親,累死你的。那么該如何解決這個問題呢?答案就是為每一個Excel模版配置一個Xml配置文件。有多少個Excel模版,就為他配多少個Xml配置文件,當然我們這里假定每一個Excel模版的格式都是不同的。
          我們將一個配置文件區分成這樣的四個部分:頭部-<Header>、身體-<Body name="Tap1" startRow="10" finishRow="22" sheetIndex="0">、腳部-<Footer>和圖片部分-<Images>。在實際應用中主要存在這樣兩種特殊情況:1、Excel模版中存在多個<Body>屬性,這種情況往往意味著您要在Excel中打印出多個Sheet頁;2、Excel模版中要求寫入多個圖片,這種情況又分為:2.1、在第一個Sheet頁中寫入多個圖片;2.2、有多個<Body>節點,要求在Excel中打印出多個Sheet頁,每個Sheet頁中寫入一個圖片。當然2.1和2.2這兩種情況比較極端和少見了。針對這種極端情況,我的源代碼中沒有去實現,因為很少用上所以筆者偷懶了。如果您看懂了代碼相信您自己動手更改完全沒有問題。因為在我看來還是不太難的。
           情況2的多圖片寫入情況排除。在這個代碼中只針對在Excel 第一個Sheet頁寫入一個圖片的情況去討論。程序的設計思路可以這樣描述:從外部系統中接到一個輸入流,和Xml配置文件中的定義內容做對比,找到Excel模版,寫入。在Xml配置文件中

 <Header> 節點下內容:

hf52v~)hx)0x5@s__l1ip4o.jpg
<Header>節點下存在多個<Field>節點,每一個<Field>節點代表一個Excel中的單元格,其下的<name>節點代表外部系統中傳入的Map流中Key值,這個Key值與這里的<name>節點屬性做匹配,如果成功則在對應的單元格寫入。<beginRow>節點和<beginCell>節點唯一確定了一個Excel模版的單元格。
<Body>節點下內容:

1.png
name屬性:表示這個<Body>節點的名稱;startRow屬性:表示這個<Body>節點的起始行; finishRow屬性:表示這個<Body>節點的結束行;sheetIndex屬性:表示這個<Body>節點要寫在Excel模版中的第幾個Sheet頁中。默認是0,因為Excel中Sheet是從0開始算起的,這個要注意。由于Excel中的身體部分(Body)是作為循環去輸出到Excel中的,所以這里的<beginCell>節點代表他的起始列。
<Footer>節點下內容:

2.png
與</span> <Header> </span> 相同,不再熬述。
<Images>節點下內容:

3.png

這里面的內容您要自己嘗試配置一下,同時看看代碼中的注釋就可以了解,這里不再針對他單獨介紹。

</span>

源代碼

ReportBulider.java

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO; import javax.imageio.stream.ImageInputStream;

import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFClientAnchor; import org.apache.poi.hssf.usermodel.HSSFPatriarch; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory;

public class ReportBuilder { //==============================================================================// private static Logger log = LoggerFactory.getLogger(ReportBuilder.class); FileOutputStream fileOutputStream = null; HSSFWorkbook workBook = null; HSSFSheet sheet = null; HSSFPatriarch patriarch = null; //==============================================================================//

//==============================================================================//
/**
 * @用途:重載+1。加載一個已經存在的模板,將生成的內容保存到 workbook中
 * @參數:String templateFile:指索要加載的模板的路徑,如:"C:/Tamplates/texting-1.xls"
 * @用法:templateFile: String templateFile_Name1 = "C:/Tamplates/texting-1.xls"               
 * @author Yangcl
 */
public void loadTemplate(String templateURL)
{
    if (templateURL == null || templateURL.trim().equals(""))
    {
        // 文件不能為空提示
        throw new RuntimeException("文件模板路徑不能為空");
    }

    try
    {
        FileInputStream templateFile_Input = new FileInputStream(templateURL);          
        POIFSFileSystem fs = new POIFSFileSystem(templateFile_Input);
        workBook = new HSSFWorkbook(fs);
        sheet = workBook.getSheetAt(0);
    }
    catch (Exception e)
    {
        log.error("loadTemplate()方法異常,文件加載失敗:", e.toString());
    }
}
public void loadTemplate(InputStream templateStream)
{
    try
    {
        POIFSFileSystem fs = new POIFSFileSystem(templateStream);
        workBook = new HSSFWorkbook(fs);
        sheet = workBook.getSheetAt(0);
    }
    catch (Exception e)
    {
        log.error("loadTemplate()方法異常,文件加載失敗:", e.toString());
    }
}
//==============================================================================//
private void checkAndAddSheet(int sheetIndex)
{
    if (sheetIndex + 1 > workBook.getNumberOfSheets())
    {
        for (int i = 0; i < sheetIndex + 1 - workBook.getNumberOfSheets(); i++)
        {
            sheet = workBook.createSheet();
        }
    }
    else
    {
        sheet = workBook.getSheetAt(sheetIndex);
    }
}
//==============================================================================//
/**
 * 寫入非圖片格式信息,重載+3
 * 
 * @描述:這是一個實體類,提供了相應的接口,用于操作Excel,在任意坐標處寫入數據。
 * @參數:String newContent:你要輸入的內容 
 *        int beginRow :行坐標,Excel從 0 算起 
 *        int beginCol:列坐標,Excel從 0 算起         
 * @author Yangcl
 */
public void writeInTemplate(String newContent, int beginRow, int beginCell)
{
    sheet = workBook.getSheetAt(0);
    HSSFRow row = sheet.getRow(beginRow); 
    if (null == row)
    {
        row = sheet.createRow(beginRow);
    } 
    HSSFCell cell = row.getCell(beginCell); 
    if (null == cell)
    {
        cell = row.createCell(beginCell);
    } 
    cell.setCellType(HSSFCell.CELL_TYPE_STRING); 
    cell.setCellValue(newContent);
}

/**
 * 寫入非圖片格式信息,針對Excel存在多個sheet的情況。
 */
public void writeInTemplate(int sheetIndex, String newContent,  int beginRow, int beginCell)
{
    checkAndAddSheet(sheetIndex);
    HSSFRow row = sheet.getRow(beginRow);
    if (null == row)
    { 
        row = sheet.createRow(beginRow);
    }
    HSSFCell cell = row.getCell(beginCell);
    if (null == cell)
    { 
        cell = row.createCell(beginCell); 
    } 
    cell.setCellType(HSSFCell.CELL_TYPE_STRING); 
    cell.setCellValue(newContent);
}
//==============================================================================//
/**
 * 寫入圖片格式信息,重載+1
 * 
 * @param dx1:第一個cell開始的X坐           
 * @param dy1:第一個cell開始的Y坐標            
 * @param dx2:第二個cell開始的X坐標        
 * @param dy2:第二個cell開始的Y坐標
 * @param col1:圖片的左上角放在第幾個列cell (the column(o based); of the first cell)
 * @param row1:圖片的左上角放在第幾個行cell (the row(o based); of the first cell)
 * @param col2:圖片的右下角放在第幾個列cell (the column(o based); of the second cell)
 * @param row2:圖片的右下角放在第幾個行cell (the row(o based); of the second cell)
 *            
 * @描述:這是一個實體類,提供了相應的接口,用于操作Excel,在任意坐標處寫入數據。
 * @參數: String imageFileURL:他接受一個外界傳入的圖片路徑,圖片以 *.jpeg 形式存在。
 * @用法: ReportBuilder twi = new ReportBuilder(); 
 *        String imageFileURL ="D:/workspace/Tamplates/1.jpeg"; 
 *        twi.writeInTemplate(imageFileURL ,0,0, 0, 0, (short)6, 5, (short)8, 8);     
 * @author Yangcl
 */
public void writeInTemplate(String imageFileURL, int dx1, int dy1, int dx2,int dy2, short col1, int row1, short col2, int row2)
{
    BufferedImage bufferImage = null;

    // 寫入圖片格式信息
    try
    {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        // 先把讀入的圖片放到第一個 ByteArrayOutputStream 中,用于產生ByteArray
        File fileImage = new File(imageFileURL);
        bufferImage = ImageIO.read(fileImage);
        ImageIO.write(bufferImage, "JPG", byteArrayOutputStream);
        System.out.println("ImageIO 寫入完成");

        // 準備插入圖片
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
        HSSFClientAnchor anchor = new HSSFClientAnchor(dx1, dy1, dx2, dy2,
                col1, row1, col2, row2);

        // 插入圖片
        byte[] pictureData = byteArrayOutputStream.toByteArray();
        int pictureFormat = HSSFWorkbook.PICTURE_TYPE_JPEG;
        int pictureIndex = workBook.addPicture(pictureData, pictureFormat);
        patriarch.createPicture(anchor, pictureIndex);

    }
    catch (Exception e)
    {
        log.error("IO Erro:", e);
    }
    finally
    {
        if (fileOutputStream != null)
        {
            try
            {
                fileOutputStream.close();
            }
            catch (IOException io)
            {
                log.error(io.toString());
            }
        }
    }
}
/**
 * 圖片流寫入
 * @param imageInputStream
 * @param dx1
 * @param dy1
 * @param dx2
 * @param dy2
 * @param col1
 * @param row1
 * @param col2
 * @param row2
 */
public void writeInTemplate(ImageInputStream imageInputStream, int dx1,int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2)
{
    BufferedImage bufferImage = null;
    // 寫入圖片格式信息
    try
    {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        // 先把讀入的圖片放到一個 ByteArrayOutputStream 中,用于產生ByteArray
        bufferImage = ImageIO.read(imageInputStream);
        ImageIO.write(bufferImage, "JPG", byteArrayOutputStream);
        System.out.println("ImageIO 寫入完成");

        // 準備插入圖片
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
        HSSFClientAnchor anchor = new HSSFClientAnchor(dx1, dy1, dx2, dy2,
                col1, row1, col2, row2);

        // 插入圖片
        byte[] pictureData = byteArrayOutputStream.toByteArray();
        int pictureFormat = HSSFWorkbook.PICTURE_TYPE_JPEG;
        int pictureIndex = workBook.addPicture(pictureData, pictureFormat);
        patriarch.createPicture(anchor, pictureIndex);
    }
    catch (Exception e)
    {
        log.error("IO Erro:", e);
    }
    finally
    {
        if (fileOutputStream != null)
        {
            try
            {
                fileOutputStream.close();
            }
            catch (IOException io)
            {
            }
        }
    }
}
//==============================================================================//
/**
 * 保存模板 
 * @param templateFile
 * @描述:這個方法用于保存workbook(工作薄)中的內容,并寫入到一個Excel文件中
 * @參數:String templateFile:取得已經保存的類模板 路徑名稱
 * 
 * @用法:templateFile:String templateFile_Name1 = "C:/Tamplates/texting-1.xls"
 *        TemplateAdapter ta = new TemplateAdapter();
 *        ta.SaveTemplate(templateFile_Name1);
 */
public void SaveTemplate(String templateFile)
{
    try
    {
        // 建立輸出流
        fileOutputStream = new FileOutputStream(templateFile);
        workBook.write(fileOutputStream);
    }
    catch (Exception e)
    {
        log.error("IO Erro", e);
    }
    finally
    {
        if (fileOutputStream != null)
        {
            try
            {
                fileOutputStream.close();
            }
            catch (IOException io)
            {
                log.error(io.toString());
            }
        }
    }
}

}</pre></span>

ReportManager.java

package manager;

import java.io.File; import java.lang.reflect.Type; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry;

import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.SAXReader;

import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import com.hongbo.antichem.ReportBuilder;

import entity.BodyField; import entity.GenericField; import entity.ImageField;

public class ReportManager { private Document document = null;//org.dom4j.Document private ReportBuilder builder; private Element bodyElement = null;

private List<GenericField>    heads       = null;
private Map<String,List<BodyField>>     bodys       = null;
private List<GenericField>    foots       = null;
private List<ImageField>  image       = null;


public ReportBuilder getBuilder()
{
    return builder;
}

public void setBuilder(ReportBuilder builder)
{
    this.builder = builder;
}
//==============================================================================//
/**
 * @描述:這個方法用于加載Xml配置文件,取得節點中的所有信息。
 * @author Yangcl
 */
private void loadXmlMapping(String mappingURL)
{
    File xmlConfigFile = new File(mappingURL);
    SAXReader saxReader = new SAXReader();
    try
    {
        document = saxReader.read(xmlConfigFile);//org.dom4j.Document
    }
    catch (DocumentException e)
    { 
        e.printStackTrace();
    }

    Element rootElement = document.getRootElement();// 獲取根節點:ReportMapping
    heads = head(rootElement);
    bodys = body(rootElement);
    foots = foot(rootElement);
    image = image(rootElement);

}
//==============================================================================//
/**
 * 分別遍歷xml文件的head\body\foot\image 
 */
private List<GenericField> head(Element rootElement)
{
    List<GenericField> headerList = new ArrayList<GenericField>(); 
    Element headerElement = rootElement.element("Header"); 
    for (Iterator iter = headerElement.elementIterator(); iter.hasNext();)
    {
        Element element = (Element) iter.next(); 
        // 取得Field節點下 <name>的值
        String xml_Name = element.elementTextTrim("name"); 
        String xml_Row = element.elementTextTrim("beginRow");
        String xml_Cell = element.elementTextTrim("beginCell");

        int intFieldRow = new Integer(xml_Row);
        int intFieldCell = new Integer(xml_Cell);

        // 放入實體類中
        GenericField gf = new GenericField();
        gf.setName(xml_Name); 
        gf.setBeginRow(intFieldRow);
        gf.setBeginCell(intFieldCell); 
        headerList.add(gf);
    }
    return headerList;
}

private Map<String,List<BodyField>> body(Element rootElement)
{
    //存放Body節點。以其屬性name為Key,節點List為Value
    Map<String,List<BodyField>> bodyMaps = new HashMap<String,List<BodyField>>();

    @SuppressWarnings("unchecked")
    List<Element> bodyEleList = rootElement.elements("Body");//<Body>節點list集合
    for(Iterator ite = bodyEleList.iterator();ite.hasNext();)//遍歷其中的一個<Body>節點
    {   //<Body name="Tap1" startRow="10" finishRow="22" sheetIndex="2">
        Element element = (Element) ite.next();

        String bodyName = element.attribute("name").getValue();
        String startRow = element.attribute("startRow").getValue();
        String finishRow = element.attribute("finishRow").getValue();
        String sheetIndex = element.attribute("sheetIndex").getValue();
        String Key = bodyName + "/" + startRow + "/" + finishRow + "/" + sheetIndex;

        List<BodyField> bodylist = new LinkedList<BodyField>(); // 存儲Body所有節點  
        for (Iterator iter = element.elementIterator(); iter.hasNext();)
        {
            Element ele = (Element) iter.next();
            String xml_Name = ele.elementTextTrim("name"); 
            String xml_Cell = ele.elementTextTrim("beginCell"); 

            int intFieldCell = new Integer(xml_Cell); 
            BodyField bf = new BodyField();         
            bf.setName(xml_Name); 
            bf.setBeginCell(intFieldCell);
            bodylist.add(bf); 
        }
        bodyMaps.put(Key, bodylist);

    } 
    return bodyMaps;
}
private List<BodyField> body1(Element rootElement)
{
    List<BodyField> bodylist = new LinkedList<BodyField>();// 存儲Body所有節點

    bodyElement = rootElement.element("Body"); 
    for (Iterator iter = bodyElement.elementIterator(); iter.hasNext();)
    { 
        Element element = (Element) iter.next(); 
        String xml_Name = element.elementTextTrim("name"); 
        String xml_Cell = element.elementTextTrim("beginCell");//這個變量會用到

        int intFieldCell = new Integer(xml_Cell);

        BodyField bf = new BodyField();         
        bf.setName(xml_Name); 
        bf.setBeginCell(intFieldCell);
        bodylist.add(bf);
    } 
    return bodylist;
}
private List<GenericField> foot(Element rootElement)
{
    List<GenericField> footlist = new LinkedList<GenericField>(); 
    Element footElement = rootElement.element("Footer");
    for (Iterator iter = footElement.elementIterator(); iter.hasNext();)
    {
        Element element = (Element) iter.next(); 
        String xml_Name = element.elementTextTrim("name"); 
        String xml_Row = element.elementTextTrim("beginRow");
        String xml_Cell = element.elementTextTrim("beginCell");

        // 轉換為 int類型數據 
        int intFieldRow = new Integer(xml_Row);
        int intFieldCell = new Integer(xml_Cell);

        // 放入實體類中
        GenericField gf = new GenericField();
        gf.setName(xml_Name); 
        gf.setBeginRow(intFieldRow);
        gf.setBeginCell(intFieldCell);

        footlist.add(gf);
    }
    return footlist;
}
private List<ImageField> image(Element rootElement)
{
    List<ImageField> imagelist = new LinkedList<ImageField>();
    Element imageElement = rootElement.element("Images");

    for (Iterator iter = imageElement.elementIterator(); iter.hasNext();)
    {
        Element element = (Element) iter.next();
        String xml_Name = element.elementTextTrim("name");
        //表示圖片是以文本形式還是文件流形式寫入
        String xml_ImageInputStream = element.elementTextTrim("imageInputStream");
        String xml_Dx1 = element.elementTextTrim("Dx1");
        String xml_Dy1 = element.elementTextTrim("Dy1");
        String xml_Dx2 = element.elementTextTrim("Dx2");
        String xml_Dy2 = element.elementTextTrim("Dy2");
        String xml_shortCol1 = element.elementTextTrim("shortCol1");
        String xml_row1 = element.elementTextTrim("row1");
        String xml_shortCol2 = element.elementTextTrim("shortCol2");
        String xml_row2 = element.elementTextTrim("row2");

        // 轉換數據類型
        int intFieldDx1 = new Integer(xml_Dx1);
        int intFieldDy1 = new Integer(xml_Dy1);
        int intFieldDx2 = new Integer(xml_Dx2);
        int intFieldDy2 = new Integer(xml_Dy2);
        short intFieldCol1 = new Short(xml_shortCol1);
        int intFieldRow1 = new Integer(xml_row1);
        short intFieldCol2 = new Short(xml_shortCol2);
        int intFieldRow2 = new Integer(xml_row2);

        // 放入實體類中
        ImageField image = new ImageField();
        image.setName(xml_Name);
        image.setImageInputStream(xml_ImageInputStream);
        image.setDx1(intFieldDx1);
        image.setDy1(intFieldDy1);
        image.setDx2(intFieldDx2);
        image.setDy2(intFieldDy2);
        image.setShortCol1(intFieldCol1);
        image.setRow1(intFieldRow1);
        image.setShortCol2(intFieldCol2);
        image.setRow2(intFieldRow2);

        imagelist.add(image);
    }
    return imagelist;

}
//==============================================================================//

private void process(Map map)
{
    Iterator mapIter = map.entrySet().iterator();

    while (mapIter.hasNext())
    {
        Entry me = (Entry) mapIter.next();
        String name = (String) me.getKey(); // 取出外部map傳入的 Key 值
        Object value = (Object) me.getValue();// 取出外部map傳入的 value 值

// System.out.println("Json Name = "+name); for (int i = 0; i < heads.size(); i++) {

            if (heads.get(i).getName().equals(name))
            {
                String values = (String) value;
                int beginRow = heads.get(i).getBeginRow();
                int beginCell = heads.get(i).getBeginCell();
                getBuilder().writeInTemplate(values, beginRow, beginCell);
                break;
            }
        }

        Iterator ite = bodys.entrySet().iterator();
        System.out.println(bodys.size());
        while(ite.hasNext())
        {
            Entry en = (Entry) ite.next();
            String Key = (String) en.getKey();//取出Body的屬性名稱 
            String [] s =Key.split("/");
            System.out.println(Key);//////////////////////////////////////

            String bodyName = s[0];
            String aa = s[1];
            String bb = s[2];
            String cc = s[3];
            int startRow = new Integer(aa); // 強制轉化為 int
            int finishRow = new Integer(bb);
            int sheetIndex = new Integer(cc);

            List<BodyField> bodyListValue = (List<BodyField>) en.getValue();

            if(bodyName.equals(name))
            {
                int number = 1;//為Excel中的序號+1

                List<Map<String,String>> listValue = (List<Map<String,String>>) value;

                for (int a = 0; a < listValue.size(); a++)
                {
                    Map<String, String> bodyMap = (Map<String, String>) listValue.get(a);
                    Iterator bodyIter = bodyMap.entrySet().iterator();

                    for(BodyField bodyField : bodyListValue)
                    {
                        if(bodyField.getName().equals("SerialNumber"))
                        {
                            String valueBody = Integer.toString(number);
                            getBuilder().writeInTemplate(sheetIndex, valueBody, startRow - 1, 0);
                        }
                    }

                    while (bodyIter.hasNext())
                    {
                        Entry meBody = (Entry) bodyIter.next();
                        String nameBody = String.valueOf(meBody.getKey());
                        String valueBody = String.valueOf(meBody.getValue());
                        for (BodyField bodyField : bodyListValue)
                        {
                            if (bodyField.getName().equals(nameBody))
                            {
                                int beginCell = bodyField.getBeginCell();
                                //getBuilder().writeInTemplate(valueBody, startRow - 1, beginCell);
                                getBuilder().writeInTemplate(sheetIndex, valueBody, startRow - 1, beginCell);
                            }
                        } 
                    }

// if (startRow < finishRow) // { // startRow++; // } if(finishRow == 0) { startRow++; number++; } else if(finishRow > 0) { if(startRow < finishRow) { startRow++; number++; } }

                }
            }

        }
        for (int j = 0; j < foots.size(); j++)
        {
            if (foots.get(j).getName().equals(name))
            {
                String values = (String) value;
                int beginRow = foots.get(j).getBeginRow();
                int beginCell = foots.get(j).getBeginCell();

// System.out.println("values:"+values+"\n"); // System.out.println("beginRow:"+beginRow+" beginCell:" + beginCell+"\n");

                getBuilder().writeInTemplate(values, beginRow, beginCell);
                break;
            }

        }

        for (int k = 0; k < image.size(); k++)
        {
            if (image.get(k).getName().equals(name))
            {
                String values = (String) value;
                int dx1 = image.get(k).getDx1();
                int dy1 = image.get(k).getDy1();
                int dx2 = image.get(k).getDx2();
                int dy2 = image.get(k).getDy2();
                short col1 = image.get(k).getShortCol1();
                int row1 = image.get(k).getRow1();
                short col2 = image.get(k).getShortCol2();
                int row2 = image.get(k).getRow2();

                getBuilder().writeInTemplate(values, dx1, dy1, dx2, dy2,col1, row1, col2, row2);
                break;
            }
        }
    }
}

private void processData(String jsonString)
{
    GsonBuilder gbuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd").registerTypeAdapter(Object.class, new NaturalDeserializer());
    Gson gson = gbuilder.create();
    Object natural = gson.fromJson(jsonString, Object.class);

    Map gsonMap = (Map) natural;
    // 解析并遍歷Map
    process(gsonMap);

}

private static class NaturalDeserializer implements JsonDeserializer<Object>
    {
        // 請參考:http://stackoverflow.com/questions/2779251/convert-json-to-hashmap-using-gson-in-java
        public Object deserialize(JsonElement json, Type typeOfT,
                JsonDeserializationContext context)
        {
            if (json.isJsonNull())
                return null;
            else if (json.isJsonPrimitive())
                return handlePrimitive(json.getAsJsonPrimitive());
            else if (json.isJsonArray())
                return handleArray(json.getAsJsonArray(), context);
            else
                return handleObject(json.getAsJsonObject(), context);
        }

        private Object handlePrimitive(JsonPrimitive json)
        {
            if (json.isBoolean())
                return json.getAsBoolean();
            else if (json.isString())
                return json.getAsString();
            else
            {
                BigDecimal bigDec = json.getAsBigDecimal();
                // Find out if it is an int type
                try
                {
                    bigDec.toBigIntegerExact();
                    try
                    {
                        return bigDec.intValueExact();
                    }
                    catch (ArithmeticException e)
                    {

                    }

                    return bigDec.longValue();
                }
                catch (ArithmeticException e)
                {

                }
                // Just return it as a double
                return bigDec.doubleValue();
            }
        }

        private Object handleArray(JsonArray json,JsonDeserializationContext context)
        {
            Object[] array = new Object[json.size()];

            for (int i = 0; i < array.length; i++)
            {
                array[i] = context.deserialize(json.get(i), Object.class);
            }

            return array;
        }

        private Object handleObject(JsonObject json,JsonDeserializationContext context)
        {
            Map<String, Object> map = new HashMap<String, Object>();
            for (Entry<String, JsonElement> entry : json.entrySet())
            {
                map.put(entry.getKey(),
                        context.deserialize(entry.getValue(), Object.class));
            }

            return map;
        }

    }

public void doReport(String excelURL,String xmlURL,String jsonString,String saveURL)
{
    ReportBuilder rb = new ReportBuilder(); 
    rb.loadTemplate(excelURL); 
    this.setBuilder(rb);
    this.loadXmlMapping(xmlURL); 
    this.processData(jsonString);
    rb.SaveTemplate(saveURL);
}

}</pre></span>

實體類

public class BodyField 
{
    private String name;
    private int BeginCell;

public int getBeginCell() 
{
    return BeginCell;
}

public void setBeginCell(int beginCell) 
{
    BeginCell = beginCell;
}


public String getName() 
{
    return name;
}

public void setName(String name) 
{
    this.name = name;
}

}

ublic class GenericField { private String name; private int beginRow; private int beginCell;

public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getBeginRow() {
    return beginRow;
}
public void setBeginRow(int beginRow) {
    this.beginRow = beginRow;
}
public int getBeginCell() {
    return beginCell;
}
public void setBeginCell(int beginCell) {
    this.beginCell = beginCell;
}

}

public class ImageField { private String name; private String imageInputStream; private int Dx1; private int Dy1; private int Dx2; private int Dy2; private int row1; private int row2; private short shortCol1; private short shortCol2;

public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getImageInputStream() {
    return imageInputStream;
}
public void setImageInputStream(String imageInputStream) {
    this.imageInputStream = imageInputStream;
}
public int getDx1() {
    return Dx1;
}
public void setDx1(int dx1) {
    Dx1 = dx1;
}
public int getDy1() {
    return Dy1;
}
public void setDy1(int dy1) {
    Dy1 = dy1;
}
public int getDx2() {
    return Dx2;
}
public void setDx2(int dx2) {
    Dx2 = dx2;
}
public int getDy2() {
    return Dy2;
}
public void setDy2(int dy2) {
    Dy2 = dy2;
}
public int getRow1() {
    return row1;
}
public void setRow1(int row1) {
    this.row1 = row1;
}
public int getRow2() {
    return row2;
}
public void setRow2(int row2) {
    this.row2 = row2;
}
public short getShortCol1() {
    return shortCol1;
}
public void setShortCol1(short shortCol1) {
    this.shortCol1 = shortCol1;
}
public short getShortCol2() {
    return shortCol2;
}
public void setShortCol2(short shortCol2) {
    this.shortCol2 = shortCol2;
}   

}</pre>
</span>

測試類

package manager;

import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;

import com.google.gson.Gson;

/**

  • 這是一個單元測試類
  • @author user */ public class ActionTest { public static void main(String[] args) {

     Map<String, Object> valueMap = new HashMap<String, Object>();
     valueMap.put("number", "100867721");
     valueMap.put("date", "2012/08/03");
     valueMap.put("storeNum", "99999999");
     valueMap.put("remarks", "中  華   人   民   共   和   國   萬   歲   !!");
     valueMap.put("imageStream", "E:\\work\\workspace\\運行域\\Tamplates\\1.JPEG");
     valueMap.put("CustodyCaptain", "李軍");
     valueMap.put("Storeman", "周勇瀟");
     valueMap.put("BusinessAssistant", "李晨東");
    
     List<Map<String, String>> list1 = new ArrayList<Map<String, String>>();
     Map<String, String> bodyMap = new HashMap<String, String>();
     bodyMap.put("SerialNumber", "1");
     bodyMap.put("Name", "器材");
     bodyMap.put("BatchNumber", "ZZFH-0083299");
     bodyMap.put("Unit", "1");// 單位
     bodyMap.put("New", "1"); // 新品
     bodyMap.put("Prospect", "1"); // 堪品
     bodyMap.put("Defective", "1"); // 廢品
     bodyMap.put("R-New", "1");
     bodyMap.put("R-Prospect", "1");
     bodyMap.put("R-Defective", "1");
     bodyMap.put("D-New", "1");// D :deducting,差異,扣除
     bodyMap.put("D-Prospect", "1");
     bodyMap.put("D-Defective", "1");
     bodyMap.put("remarks", "無");
     list1.add(bodyMap);
     Map<String, String> bodyMap1 = new HashMap<String, String>();
     bodyMap1.put("SerialNumber", "2");
     bodyMap1.put("Name", "器材");
     bodyMap1.put("BatchNumber", "2");
     bodyMap1.put("Unit", "2");// 單位
     bodyMap1.put("New", "2"); // 新品
     bodyMap1.put("Prospect", "2"); // 堪品
     bodyMap1.put("Defective", "2"); // 廢品
     bodyMap1.put("R-New", "2");
     bodyMap1.put("R-Prospect", "2");
     bodyMap1.put("R-Defective", "2");
     bodyMap1.put("D-New", "2");// D :deducting,差異,扣除
     bodyMap1.put("D-Prospect", "2");
     bodyMap1.put("D-Defective", "2");
     bodyMap1.put("remarks", "無");
     list1.add(bodyMap1); 
     Map<String, String> bodyMap2 = new HashMap<String, String>();
     bodyMap2.put("SerialNumber", "3");
     bodyMap2.put("Name", "器材0000");
     bodyMap2.put("BatchNumber", "0");
     bodyMap2.put("Unit", "0");// 單位
     bodyMap2.put("New", "0"); // 新品
     bodyMap2.put("Prospect", "0"); // 堪品
     bodyMap2.put("Defective", "0"); // 廢品
     bodyMap2.put("R-New", "0");
     bodyMap2.put("R-Prospect", "0");
     bodyMap2.put("R-Defective", "0");
     bodyMap2.put("D-New", "0");// D :deducting,差異,扣除
     bodyMap2.put("D-Prospect", "0");
     bodyMap2.put("D-Defective", "0");
     bodyMap2.put("remarks", "無000");
     list1.add(bodyMap2); 
     valueMap.put("Tap1", list1);
    List<Map<String, String>> list2 = new ArrayList<Map<String, String>>();
    Map<String, String> bodyMap3 = new HashMap<String, String>();
    bodyMap3.put("SerialNumber", "3");
    bodyMap3.put("Name", "器材");
    bodyMap3.put("BatchNumber", "ZZFH-0083299");
    bodyMap3.put("Unit", "3");// 單位
    bodyMap3.put("New", "3"); // 新品
    bodyMap3.put("Prospect", "3"); // 堪品
    bodyMap3.put("Defective", "3"); // 廢品
    bodyMap3.put("R-New", "3");
    bodyMap3.put("R-Prospect", "3");
    bodyMap3.put("R-Defective", "3");
    bodyMap3.put("D-New", "3");// D :deducting,差異,扣除
    bodyMap3.put("D-Prospect", "3");
    bodyMap3.put("D-Defective", "3");
    bodyMap3.put("remarks", "無");
    list2.add(bodyMap3);
    Map<String, String> bodyMap4 = new HashMap<String, String>();
    bodyMap4.put("SerialNumber", "4");
    bodyMap4.put("Name", "器材");
    bodyMap4.put("BatchNumber", "4");
    bodyMap4.put("Unit", "4");// 單位
    bodyMap4.put("New", "4"); // 新品
    bodyMap4.put("Prospect", "4"); // 堪品
    bodyMap4.put("Defective", "4"); // 廢品
    bodyMap4.put("R-New", "4");
    bodyMap4.put("R-Prospect", "4");
    bodyMap4.put("R-Defective", "4");
    bodyMap4.put("D-New", "4");// D :deducting,差異,扣除
    bodyMap4.put("D-Prospect", "4");
    bodyMap4.put("D-Defective", "4");
    bodyMap4.put("remarks", "無");
    list2.add(bodyMap4);

    valueMap.put("Tap2", list2);

    Gson gson = new Gson();
    String jsonString = gson.toJson(valueMap); 
    System.out.println(jsonString);
    String excelURL =   "E:\\work\\workspace\\運行域\\Tamplates\\TamplateTest-4.xls";
    String xmlURL =     "E:\\work\\workspace\\運行域\\Tamplates\\config.xml";
    String saveURL =    "E:\\work\\workspace\\運行域\\TamplatesUser\\test6.xls";
    ReportManager rm = new ReportManager();
    rm.doReport(excelURL, xmlURL, jsonString, saveURL);
}

}</pre>
以下是依賴包

4.png
項目工程如下:
</span>  http://download.csdn.net/detail/breatheryang/5047499 


 本文由用戶 Yangcl 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!