關于多條件檢索和數據導出word表格及合并
1.項目搭建
1.1 框架生成
采用的是renren-fast的后臺腳手架框架,是人人開源社區采用Spring、MyBatis、Shiro編寫的;
1.1.1 建立數據庫表
? 搭建完成后,先需要建立好數據庫的所有數據表,以便代碼生成器生成
1.1.2 代碼生成器
? 隨后利用代碼生成器生成相應實體的controller,service,dao,entity實體以及mapper中的xml映射文件。
1.1.3 業務層修改
? 基本的增刪改查具有了,接下來就根據實際的業務需求修改代碼(主要針對業務邏輯層)
2.列表查詢(檢索)
2.1 內容梳理
表內容組成:
? 產品配方主表 P:(物料suppliesCode,原膜memType,產品名稱productName,id)
? 字表 S:配方子表(顏色color,對應區域fileUrl,header_id)
? 字表 S2:配色明細(廠家inkFactor,油墨inkName,型號model,配比propertion,header_id)
2.1.1 建立關系
? 建立好主表和相應字表間的關系,字表作為成員變量存放在主表中
2.1.2 處理
? 點擊進入詳情,傳入主表id,找到對應的S表,再利用S表id找到S2表,逐層封裝,最后返回給前端
? 條件搜索,能夠確定唯一的產品
2.2 思路解決
? 因為最后的配方列表需要將s2表的內容組裝起來,所以先將產品名稱-p表、顏色-s表、對應區域-s表進行表連接,然后再將s2表中的數據拼接為配方需要的字符串信息,再將兩張表拼接起來。
2.2.2 sql語句
-- 先嘗試將s2的信息拼接成功,成一張新表
SELECT
header_id,
GROUP_CONCAT( model, '(', ink_name, '):', proportion, '%' ) AS info
FROM
bo_packprint_recp_s2
GROUP BY
header_id
-- 再將新表和產品、顏色、對應區域部分進行拼接,即可達到上圖的檢索效果
SELECT
p.product_name,
s.color,
s.file_url,
pf.info
FROM
bo_packprint_recp_p AS p
LEFT JOIN bo_packprint_recp_s AS s ON p.id = s.header_id
LEFT JOIN bo_packprint_recp_s2 AS s2 ON s.id = s2.header_id
LEFT JOIN (
SELECT
header_id,
GROUP_CONCAT( model, '(', ink_name, '):', proportion, '%' ) AS info
FROM
bo_packprint_recp_s2
GROUP BY
header_id) AS pf ON s.id = pf.header_id
WHERE
s.color LIKE '%藍%' AND
s2.ink_name LIKE '%原藍%' AND
p.product_name LIKE '%蘇打水%' AND
p.mem_type LIKE '%透明膜%'
3.word表格的文檔導出功能
3.1 導出要求梳理
效果圖中涉及到數據的替換,動態插入數據和圖片,根據要求合并單元格。
3.1.1 繪制模板
? 首先,進行模板的繪制,將固定替換的位置標注出來。
3.1.2 替換表格里固定位置的變量
? 將表格的內容進行遍歷,如果表格單元格中的內容包含${},則執行替換的操作
3.1.3 進行動態數據的插入
? 根據實際數據個數,增加模板行數。
? 插入數據,圖片轉換為字節輸入流保存,先插入數據,再進行判斷合并。
動態添加數據和圖片,并進行合并單元格操作的代碼部分:
模板:
private static void insertTable(XWPFTable table, List<String[]> tableList, Integer matrListSize) {
//創建行,根據需要插入的數據添加新行,不處理表頭
for (int i = 0; i < tableList.size(); i++) {
setTableStyle(table);
XWPFTableRow row = table.createRow();
for (int k = 1; k < tableList.get(0).length; k++) {
row.createCell();//根據String數組第一條數據的長度動態創建列
}
}
//遍歷表格插入數據
List<XWPFTableRow> rows = table.getRows();
int length = table.getRows().size();
for (int i = 3; i < length; i++) {
XWPFTableRow newRow = table.getRow(i);
List<XWPFTableCell> cells = newRow.getTableCells();
for (int j = 0; j < cells.size(); j++) {
XWPFTableCell cell = cells.get(j);
if (j == 2) {
List<XWPFParagraph> paragraphs = cell.getParagraphs();
XWPFParagraph newPara = paragraphs.get(0);
XWPFRun imageCellRunn = newPara.createRun();
try {
String fileName = tableList.get(i - 3)[j];
File file = new File(fileName);
FileInputStream is = new FileInputStream(file);
imageCellRunn.addPicture(is, getPictureType(fileName), file.getName(), Units.toEMU(70), Units.toEMU(30));
} catch (Exception e) {
e.printStackTrace();
}
} else {
cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
CTTc cttc = cell.getCTTc();
CTP ctp = cttc.getPList().get(0);
CTPPr ctpPr = ctp.getPPr();
if (ctpPr == null) {
ctpPr = ctp.addNewPPr();
}
CTJc ctJc = ctpPr.getJc();
if (ctJc == null) {
ctJc = ctpPr.addNewJc();
}
ctJc.setVal(STJc.CENTER);
String s = tableList.get(i - 3)[j];
cell.setText(s);
}
}
}
//合并單元格(對每一行的進行遍歷,根據相同的條件進行合并)
for (int n = matrListSize; n < tableList.size(); ) {
//獲取到tableList里面的序號,如果序號相同就可以進行合并
String[] strings = tableList.get(n);
String index = strings[0];
// 定義可以合并的單元行數
int mergeNumber = 0;
for (String[] strings1 : tableList) {
String s = strings1[0];
if (index.equals(s)) {
mergeNumber += 1;
}
}
// col:指定列 fromRow:從第幾行開始 toRow:從第幾行結束
mergeCellsVertically(table, 0, 3 + n, 3 + n + mergeNumber - 1);
mergeCellsVertically(table, 1, 3 + n, 3 + n + mergeNumber - 1);
mergeCellsVertically(table, 2, 3 + n, 3 + n + mergeNumber - 1);
n = n + mergeNumber;
}
}
效果圖:
NI~1\AppData\Local\Temp\1591692057388.png)]
4.總結點
4.1 關于遍歷中的遇到的問題
****
? for: 最原始的循環方式,基于索引來實現;
? 它的內容垃圾比foreach少,在遍歷的過程中能對元素本身進行增刪改的操作。
? foreach:實現便捷,基于迭代器實現(實現Iterator集合類 ),能快速循環取出元素;
? 由于底層實現原理導致不能在遍歷的過程中操作元素(增刪改),否則會拋出ConcurrentModificationException的異常,但可以對元素的已有屬性進行更改;
? 其中有兩種情況可以在foreach中實現部分修改(自己操作過),在try…catch的情況下可以進行增刪的操作,有結果但也報錯;除此之外,沒有catch的情況下刪除需要保證元素只有兩個,否則報錯(沒意義…哈哈)
4.2 通常使用的注解的作用
? @ExplicitConstraint注解
? 這各注解是一種數組方式的下拉框約束,(source={“aa”,“bb”})指定該注解修飾的字段在導出excel后能進行下拉框內容的選擇。
? @Api開頭的注解作用
? 通常是用做接口文檔Swagger的生成,在控制層,方法,實體類上添加相應注解完成接口文檔的各個部分:
@Api(tags = "產品配方主表") // 作用在類上,說明具體針對哪個實體進行操作
@ApiOperation("查詢/新增/刪除產品配方主表") // 作用在方法上,具體說明方法的作用
@ApiImplicitParams({ // 執行方法時需要的多個參數說明(名稱,含義,參數作用,數據類型)
@ApiImplicitParam(name = "memType", value = "原膜類型", paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "suppliesCode", value = "物料代碼", paramType = "query", dataType = "String")
})
@ApiModel(value="產品配方主表") // 說明實體類的含義,作用在具體的實體上面
@ApiModelProperty(value = "原膜類型") // 作用在實體類的屬性上,說明實體的屬性代表含義
// 其他常用注釋
@Excel // 報表技術常用的一種注釋,用于導出表格(創建人,id,更新時間和更新人的id不要加注釋!!!)
@ExplicitConstraint(source = {"PVC","PET透明膜","PET白膜","BOPP","珠光膜","PE"})
// 在導出excel表格后,要求能在該字段下進行多選操作,則需要該注釋,source里放入多選項。
@TableId // 修飾主鍵id
@TableName("bo_packprint_recp_p") // 對應的數據庫中的表
@TableField("order_id") // 表中的字段和實際使用的字段(orderId)是不一致的
4.3 數據類型和方法的使用
? 1、BigDecimal數據類型的特性?
? 是用于高精度計算的數據類型,有兩類:BigInteger(針對大整數的處理類)和BigDecimal(針對大小數的處理類),他們創建的是對象,不能用普通的運算符計算,需調用對應的方法,方法的參數也必須一致。
加:add 減:subtract 乘:multiply 除:divide
推薦初始化時參數string,保證精度。BigDecimal decimal = new BigDecimal(“100”)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LisGxpyS-1591749647656)(C:\Users\ADMINI~1\AppData\Local\Temp\1591020963111.png)]
? 2、==和equals, compareTo的使用?
== 比較的是值是否相等,對于基本類型數據的變量,則直接比較值是否相等;對引用類型的變量則比較指向對象的地址。
equals 方法是不能作用于基本數據類型的變量的,equals方法繼承自objec類,比較的是否為統一對象,沒有重寫的情況下比較的是引用類型的變量所指向的地址;但是String、Date類對equals方法重寫,所以比較的是內容。
compareTo:用于對象的比較和字符串的比較,大于比較對象則返回正數,小于返回負數,等于返回0;
4.4 獲得相應的路徑
? 獲得文件路徑:this.getClass().getClassLoader().getResource("")
this.getClass().getClassLoader().getResource("").getPath()
// 獲取src資源文件編譯后的路徑(即classes路徑)
getClass():獲得當前對象所屬的Class對象
getClassLoader():獲得Class對象的類加載器
// 輸出: /D:/06-hs/packprint/target/classes/
4.5、在lambda表達式中關于變量的聲明和使用?
lambda表達式不能訪問非final修飾的局部變量,因為實例變量存在堆中,而局部變量存放在棧上,lambda表達是在另外的線程上進行執行的,所以當該線程訪問局部變量的時候,該局部變量可能已經銷毀了.
final類型的局部變量則是作為原變量的拷貝副本來使用。
jdk8中不需要顯示的聲明,在表達式(匿名類)中訪問了就會強制加上final屬性,后面就無法進行賦值等修改操作了;其中實例和靜態變量是不受限制的。
4.6、代碼管理工具的使用?
? pull:將服務器上的代碼拉取到本地倉庫,每次推送代碼前拉取一次代碼,保證代碼是最新的。
? commit:把修改好的代碼提交到本地倉庫,在此之前還有個add添加操作也就是添加到暫存區。
? push:將本地倉庫的代碼接著推送到服務器上面,也就是主(master)從分支上面。
4.6、代碼管理工具的使用?
? pull:將服務器上的代碼拉取到本地倉庫,每次推送代碼前拉取一次代碼,保證代碼是最新的。
? commit:把修改好的代碼提交到本地倉庫,在此之前還有個add添加操作也就是添加到暫存區。
? push:將本地倉庫的代碼接著推送到服務器上面,也就是主(master)從分支上面。
智能推薦
Java POI導出word文件及生成表格
HWPF是處理 Microsoft Word 97(-2007) .doc文件格式,它還為較舊的Word 6和Word 95文件格式提供了有限的只讀支持。包含在poi-scratchpad-XXX.jar中。 XWPF是處理 Word 2007 .docx文件格式,包含在poi-ooxml-XXX.jar中。 &n...
SpringBoot整合poi導出word文本及表格
首先作為一名偉大的猿,是時候寫一篇博客了! 主要目的是為自己增加更深的理解,以及幫助大家能解決目前遇到的一些小問題. 本篇博客我是用springboot整合了一下poi,通過word模板導出自己想要的word文檔.(技術不高,不喜勿噴,謝謝撒~) 一、首先在pom中添加合適的依賴 這是我之前用poi導出Excel時候添加的依賴,不過嘗試用在導出word也能用,所以就沒改。 二、制作word模板,我...
3D游戲編程與設計——游戲對象與圖形基礎章節作業與練習
3D游戲編程與設計——游戲對象與圖形基礎章節作業與練習 3D游戲編程與設計——游戲對象與圖形基礎章節作業與練習 自學資源 作業內容 1、基本操作演練【建議做】 天空盒的制作: 地圖的制作: 整體效果: 2、編程實踐 項目要求: 項目結構: 代碼詳解: Actions: ISSActionCallback.cs SSAction.cs SSAction...
FlycoTabLayout 的使用
FlycoTabLayout 一個Android TabLayout庫,目前有3個TabLayout SlidingTabLayout:參照PagerSlidingTabStrip進行大量修改. 新增部分屬性 新增支持多種Indicator顯示器 新增支持未讀消息顯示 新增方法for懶癌患者 CommonTabLayout:不同于SlidingTabLayout對ViewPager依賴,它是一個不...
爬蟲項目實戰八:爬取天氣情況
爬取天氣情況 目標 項目準備 接口分析 代碼實現 效果顯示 寫入本地 目標 根據天氣接口,爬取接下來一周的天氣情況。 項目準備 軟件:Pycharm 第三方庫:requests,BeautifulSoup,csv 接口地址:http://api.k780.com:88/?app=weather.future&weaid=城市名&appkey=10003&sign=b59bc...
猜你喜歡
關于web項目的目錄問題
先給段代碼: 上面這個代碼一直出錯,我不知道原因,后面不停的查找資料發現了問題:我的web項目輸出目錄有問題,因為我也是第一次用idea寫web項目,發現很多bug 其實都沒有太大問題,我們需要注意的是你必須在out這個輸出文件夾中擁有這個文件,out輸出文件夾會默認過濾這些文件...
二叉搜索樹轉化為雙向鏈表
題目描述: 輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的循環雙向鏈表。要求不能創建任何新的節點,只能調整樹中節點指針的指向。 為了讓您更好地理解問題,以下面的二叉搜索樹為例: 我們希望將這個二叉搜索樹轉化為雙向循環鏈表。鏈表中的每個節點都有一個前驅和后繼指針。對于雙向循環鏈表,第一個節點的前驅是最后一個節點,最后一個節點的后繼是第一個節點。 下圖展示了上面的二叉搜索樹轉化成的鏈表。&ldqu...
Cocos2d-x 2.0 網格動畫深入分析
[Cocos2d-x相關教程來源于紅孩兒的游戲編程之路CSDN博客地址:http://blog.csdn.net/honghaier] 紅孩兒Cocos2d-X學習園地QQ2群:44208467加群寫:Cocos2d-x 紅孩兒Cocos2d-X學習園地QQ群:249941957[暫滿]加群寫:Cocos2d-x 本章為我的Cocos2d-x教程一書初稿。望各位看官多提建議! Cocos2d-x ...
解決Python數據可視化中文部分顯示方塊問題
一、問題 代碼如下,發現標題的中文顯示的是方塊 如下圖 二、解決方法 一般數據可視化使用matplotlib庫,設置中文字體可以在導入之后添加兩句話(這里的SimHei指的是黑體,KaiTi指的是楷體) 三、效果 1.黑體: 2.楷體: 具體的其他字體可以在matplotlib\mpl-data\fonts\ttf找到~ 四、Windows的常用字體 黑體、楷體、仿宋是可以用的,其他的字體可能需要...