ReportAnywhere Excel文檔導出程序
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設計思路

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(String 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> 節點下內容:

<Body>節點下內容:

<Footer>節點下內容:

<Images>節點下內容:

這里面的內容您要自己嘗試配置一下,同時看看代碼中的注釋就可以了解,這里不再針對他單獨介紹。
</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>
以下是依賴包項目工程如下:
</span> http://download.csdn.net/detail/breatheryang/5047499