Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
patzn-cloud-service-soil
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wangweidong
patzn-cloud-service-soil
Commits
2e72f7d9
Commit
2e72f7d9
authored
Mar 25, 2021
by
wangweidong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
土工平台修改
parent
234106b2
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
855 additions
and
1 deletions
+855
-1
ChartTest.java
...com/patzn/cloud/service/lims/gideon/create/ChartTest.java
+76
-0
ChartPosition.java
...patzn/cloud/service/lims/gideon/entity/ChartPosition.java
+109
-0
LineChart.java
...com/patzn/cloud/service/lims/gideon/entity/LineChart.java
+71
-0
PieChart.java
.../com/patzn/cloud/service/lims/gideon/entity/PieChart.java
+56
-0
ApachePoiLineChart4.java
.../cloud/service/lims/gideon/utils/ApachePoiLineChart4.java
+84
-0
ChartUtils.java
...com/patzn/cloud/service/lims/gideon/utils/ChartUtils.java
+83
-0
DrawXlsxUtil.java
...m/patzn/cloud/service/lims/gideon/utils/DrawXlsxUtil.java
+196
-0
NettyServer.java
...in/java/com/patzn/cloud/service/lims/rcp/NettyServer.java
+6
-0
Runner.java
src/main/java/com/patzn/cloud/service/lims/rcp/Runner.java
+2
-0
SoilStatisticsController.java
...ervice/lims/soil/controller/SoilStatisticsController.java
+1
-1
SoilEntrustServiceImpl.java
...ervice/lims/soil/service/impl/SoilEntrustServiceImpl.java
+43
-0
SoilExperimentServiceImpl.java
...ice/lims/soil/service/impl/SoilExperimentServiceImpl.java
+128
-0
No files found.
src/main/java/com/patzn/cloud/service/lims/gideon/create/ChartTest.java
0 → 100644
View file @
2e72f7d9
package
com
.
patzn
.
cloud
.
service
.
lims
.
gideon
.
create
;
import
com.patzn.cloud.service.lims.gideon.entity.ChartPosition
;
import
com.patzn.cloud.service.lims.gideon.entity.LineChart
;
import
com.patzn.cloud.service.lims.gideon.entity.PieChart
;
import
com.patzn.cloud.service.lims.gideon.utils.ChartUtils
;
import
org.apache.poi.xssf.usermodel.XSSFSheet
;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.util.*
;
/**
* @author GideonYeung
* @date 2020/12/3 17:14
*/
public
class
ChartTest
{
public
static
void
main
(
String
[]
args
)
throws
IOException
{
XSSFWorkbook
workbook
=
createLineChart
();
//-------------------------下载--------------------------
FileOutputStream
fileOut
=
null
;
try
{
// 将输出写入excel文件
String
filename
=
UUID
.
randomUUID
()
+
".xlsx"
;
fileOut
=
new
FileOutputStream
(
"D:\\excel_demo\\"
+
filename
);
workbook
.
write
(
fileOut
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
workbook
.
close
();
if
(
fileOut
!=
null
)
{
fileOut
.
close
();
}
}
}
/**
* 这种是直接用当数据填充
*/
public
static
XSSFWorkbook
createLineChart
()
{
XSSFWorkbook
workbook
=
new
XSSFWorkbook
();
XSSFSheet
sheet
=
workbook
.
createSheet
();
//-------------------------折线图--------------------------
List
<
LineChart
>
lineCharts
=
initLineChart
();
ChartPosition
chartPosition
;
//最后一列
int
lastRowNum
=
sheet
.
getLastRowNum
();
//图表位置左上角的开始行 +5是为了和上一个图保持五行的距离
int
chartRowStart
=
lastRowNum
+
5
;
//图表位置右上角的开始行
int
chartRowEnd
=
chartRowStart
+
20
;
for
(
LineChart
lineChart
:
lineCharts
)
{
// 图表位置(左上角坐标,右下角坐标) 左上角坐标的(列,行),(右下角坐标)列,行,偏移量均为0
chartPosition
=
new
ChartPosition
()
.
setRow1
(
chartRowStart
)
.
setCol1
(
1
)
.
setRow2
(
chartRowEnd
)
.
setCol2
(
lineChart
.
getxAxisList
().
size
()
+
3
);
ChartUtils
.
createLine
(
sheet
,
chartPosition
,
lineChart
);
}
return
workbook
;
}
public
static
List
<
LineChart
>
initLineChart
()
{
List
<
LineChart
>
lineCharts
=
new
ArrayList
<>();
lineCharts
.
add
(
new
LineChart
()
.
setChartTitle
(
"黄金当铺典当情况"
)
.
setTitleList
(
Collections
.
singletonList
(
"黄金"
))
.
setDataList
(
Collections
.
singletonList
(
Arrays
.
asList
(
11
,
21
,
31
,
41
,
51
)))
.
setxAxisList
(
Arrays
.
asList
(
"1月份"
,
"2月份"
,
"3月份"
,
"4月份"
,
"5月份"
)));
return
lineCharts
;
}
}
src/main/java/com/patzn/cloud/service/lims/gideon/entity/ChartPosition.java
0 → 100644
View file @
2e72f7d9
package
com
.
patzn
.
cloud
.
service
.
lims
.
gideon
.
entity
;
/**
* @author GideonYeung
* @date 2020/12/3 17:08
*/
public
class
ChartPosition
{
/**
* 图表的左上角坐标列
*/
private
int
col1
;
/**
* 图表的左上角坐标行
*/
private
int
row1
;
/**
* 图表的右下角坐标列
*/
private
int
col2
;
/**
* 图表的右下角坐标行t
*/
private
int
row2
;
/**
* 下面的为偏移量均设置为0
*/
private
int
dx1
=
0
;
private
int
dy1
=
0
;
private
int
dx2
=
0
;
private
int
dy2
=
0
;
public
int
getCol1
()
{
return
col1
;
}
public
ChartPosition
setCol1
(
int
col1
)
{
this
.
col1
=
col1
;
return
this
;
}
public
int
getRow1
()
{
return
row1
;
}
public
ChartPosition
setRow1
(
int
row1
)
{
this
.
row1
=
row1
;
return
this
;
}
public
int
getCol2
()
{
return
col2
;
}
public
ChartPosition
setCol2
(
int
col2
)
{
this
.
col2
=
col2
;
return
this
;
}
public
int
getRow2
()
{
return
row2
;
}
public
ChartPosition
setRow2
(
int
row2
)
{
this
.
row2
=
row2
;
return
this
;
}
public
int
getDx1
()
{
return
dx1
;
}
public
ChartPosition
setDx1
(
int
dx1
)
{
this
.
dx1
=
dx1
;
return
this
;
}
public
int
getDy1
()
{
return
dy1
;
}
public
ChartPosition
setDy1
(
int
dy1
)
{
this
.
dy1
=
dy1
;
return
this
;
}
public
int
getDx2
()
{
return
dx2
;
}
public
ChartPosition
setDx2
(
int
dx2
)
{
this
.
dx2
=
dx2
;
return
this
;
}
public
int
getDy2
()
{
return
dy2
;
}
public
ChartPosition
setDy2
(
int
dy2
)
{
this
.
dy2
=
dy2
;
return
this
;
}
}
src/main/java/com/patzn/cloud/service/lims/gideon/entity/LineChart.java
0 → 100644
View file @
2e72f7d9
package
com
.
patzn
.
cloud
.
service
.
lims
.
gideon
.
entity
;
import
java.util.List
;
/**
* 折线图数据封装
*
* @author GideonYeung
* @date 2020/12/3 14:33
*/
public
class
LineChart
{
/**
* 图表的名称
*/
private
String
chartTitle
;
/**
* 每条折线的名称
*/
private
List
<
String
>
titleList
;
/**
* 每条折线对应的数据 这里的类型根据自己的实际情况给
*/
private
List
<
List
<
Integer
>>
dataList
;
/**
* x轴 这里的类型根据自己的实际情况给
*/
private
List
<
Object
>
xAxisList
;
public
String
getChartTitle
()
{
return
chartTitle
;
}
public
LineChart
setChartTitle
(
String
chartTitle
)
{
this
.
chartTitle
=
chartTitle
;
return
this
;
}
public
List
<
String
>
getTitleList
()
{
return
titleList
;
}
public
LineChart
setTitleList
(
List
<
String
>
titleList
)
{
this
.
titleList
=
titleList
;
return
this
;
}
public
List
<
List
<
Integer
>>
getDataList
()
{
return
dataList
;
}
public
LineChart
setDataList
(
List
<
List
<
Integer
>>
dataList
)
{
this
.
dataList
=
dataList
;
return
this
;
}
public
List
<
Object
>
getxAxisList
()
{
return
xAxisList
;
}
public
LineChart
setxAxisList
(
List
<
Object
>
xAxisList
)
{
this
.
xAxisList
=
xAxisList
;
return
this
;
}
}
src/main/java/com/patzn/cloud/service/lims/gideon/entity/PieChart.java
0 → 100644
View file @
2e72f7d9
package
com
.
patzn
.
cloud
.
service
.
lims
.
gideon
.
entity
;
import
java.util.List
;
/**
* 饼图
*
* @author GideonYeung
* @date 2020/12/3 15:36
*/
public
class
PieChart
{
/**
* 饼图每块的名称
*/
private
List
<
String
>
titleList
;
/**
* 饼图每块的数据 这里的类型根据自己的实际情况给
*/
private
List
<
Integer
>
dataList
;
/**
* 饼图标题名称
*/
private
String
titleName
;
public
List
<
String
>
getTitleList
()
{
return
titleList
;
}
public
PieChart
setTitleList
(
List
<
String
>
titleList
)
{
this
.
titleList
=
titleList
;
return
this
;
}
public
List
<
Integer
>
getDataList
()
{
return
dataList
;
}
public
PieChart
setDataList
(
List
<
Integer
>
dataList
)
{
this
.
dataList
=
dataList
;
return
this
;
}
public
String
getTitleName
()
{
return
titleName
;
}
public
PieChart
setTitleName
(
String
titleName
)
{
this
.
titleName
=
titleName
;
return
this
;
}
}
src/main/java/com/patzn/cloud/service/lims/gideon/utils/ApachePoiLineChart4.java
0 → 100644
View file @
2e72f7d9
package
com
.
patzn
.
cloud
.
service
.
lims
.
gideon
.
utils
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
org.apache.poi.ss.usermodel.Cell
;
import
org.apache.poi.ss.usermodel.Row
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
org.apache.poi.xddf.usermodel.PresetLineDash
;
import
org.apache.poi.xddf.usermodel.XDDFLineProperties
;
import
org.apache.poi.xddf.usermodel.XDDFPresetLineDash
;
import
org.apache.poi.xddf.usermodel.chart.AxisPosition
;
import
org.apache.poi.xddf.usermodel.chart.ChartTypes
;
import
org.apache.poi.xddf.usermodel.chart.LegendPosition
;
import
org.apache.poi.xddf.usermodel.chart.MarkerStyle
;
import
org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis
;
import
org.apache.poi.xddf.usermodel.chart.XDDFChartLegend
;
import
org.apache.poi.xddf.usermodel.chart.XDDFDataSource
;
import
org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory
;
import
org.apache.poi.xddf.usermodel.chart.XDDFLineChartData
;
import
org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource
;
import
org.apache.poi.xddf.usermodel.chart.XDDFValueAxis
;
import
org.apache.poi.xssf.usermodel.XSSFChart
;
import
org.apache.poi.xssf.usermodel.XSSFClientAnchor
;
import
org.apache.poi.xssf.usermodel.XSSFDrawing
;
import
org.apache.poi.xssf.usermodel.XSSFSheet
;
public
class
ApachePoiLineChart4
{
public
static
void
productZhexian
(
XSSFSheet
sheet
,
DrawXlsxUtil
.
AnchorPosition
anchorPosition
)
{
try
{
//创建一个画布
XSSFDrawing
drawing
=
sheet
.
createDrawingPatriarch
();
//前四个默认0,[0,5]:从0列5行开始;[7,26]:宽度7个单元格,26向下扩展到26行
//默认宽度(14-8)*12
XSSFClientAnchor
anchor
=
drawing
.
createAnchor
(
0
,
0
,
0
,
0
,
anchorPosition
.
getCol1Index
(),
anchorPosition
.
getRow1Index
(),
anchorPosition
.
getCol2Index
(),
anchorPosition
.
getRow2Index
());
//创建一个chart对象
XSSFChart
chart
=
drawing
.
createChart
(
anchor
);
//标题
chart
.
setTitleText
(
anchorPosition
.
getyTitle
());
//标题覆盖
chart
.
setTitleOverlay
(
false
);
//图例位置
XDDFChartLegend
legend
=
chart
.
getOrAddLegend
();
legend
.
setPosition
(
LegendPosition
.
TOP
);
//分类轴标(X轴),标题位置
XDDFCategoryAxis
bottomAxis
=
chart
.
createCategoryAxis
(
AxisPosition
.
BOTTOM
);
bottomAxis
.
setTitle
(
anchorPosition
.
getxTitle
());
//值(Y轴)轴,标题位置
XDDFValueAxis
leftAxis
=
chart
.
createValueAxis
(
AxisPosition
.
LEFT
);
leftAxis
.
setTitle
(
anchorPosition
.
getyTitle
());
XDDFDataSource
<
String
>
countries
=
XDDFDataSourcesFactory
.
fromStringCellRange
(
sheet
,
new
CellRangeAddress
(
2
,
21
,
18
,
18
));
XDDFNumericalDataSource
<
Double
>
area
=
XDDFDataSourcesFactory
.
fromNumericCellRange
(
sheet
,
new
CellRangeAddress
(
2
,
21
,
19
,
19
));
//LINE:折线图,
XDDFLineChartData
data
=
(
XDDFLineChartData
)
chart
.
createData
(
ChartTypes
.
LINE
,
bottomAxis
,
leftAxis
);
//图表加载数据,折线1
XDDFLineChartData
.
Series
series1
=
(
XDDFLineChartData
.
Series
)
data
.
addSeries
(
countries
,
area
);
//折线图例标题
series1
.
setTitle
(
"面积"
,
null
);
//直线
series1
.
setSmooth
(
false
);
//设置标记大小
series1
.
setMarkerSize
((
short
)
6
);
//设置标记样式,星星
series1
.
setMarkerStyle
(
MarkerStyle
.
CIRCLE
);
//绘制
chart
.
plot
(
data
);
// 将输出写入excel文件
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
}
}
}
\ No newline at end of file
src/main/java/com/patzn/cloud/service/lims/gideon/utils/ChartUtils.java
0 → 100644
View file @
2e72f7d9
package
com
.
patzn
.
cloud
.
service
.
lims
.
gideon
.
utils
;
import
com.patzn.cloud.service.lims.gideon.entity.ChartPosition
;
import
com.patzn.cloud.service.lims.gideon.entity.LineChart
;
import
com.patzn.cloud.service.lims.gideon.entity.PieChart
;
import
org.apache.poi.xddf.usermodel.chart.*
;
import
org.apache.poi.xssf.usermodel.XSSFChart
;
import
org.apache.poi.xssf.usermodel.XSSFClientAnchor
;
import
org.apache.poi.xssf.usermodel.XSSFDrawing
;
import
org.apache.poi.xssf.usermodel.XSSFSheet
;
import
org.openxmlformats.schemas.drawingml.x2006.chart.*
;
import
org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun
;
import
org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody
;
import
org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* @author GideonYeung
* @date 2020/12/3 17:13
*/
public
class
ChartUtils
{
private
static
XSSFChart
createDrawingPatriarch
(
XSSFSheet
sheet
,
ChartPosition
chartPosition
,
String
chartTitle
)
{
//创建一个画布
XSSFDrawing
drawing
=
sheet
.
createDrawingPatriarch
();
//前偏移量四个默认0
XSSFClientAnchor
anchor
=
drawing
.
createAnchor
(
0
,
0
,
0
,
0
,
chartPosition
.
getCol1
(),
chartPosition
.
getRow1
(),
chartPosition
.
getCol2
(),
chartPosition
.
getRow2
());
//创建一个chart对象
XSSFChart
chart
=
drawing
.
createChart
(
anchor
);
//标题
chart
.
setTitleText
(
chartTitle
);
//标题是否覆盖图表
chart
.
setTitleOverlay
(
false
);
//
// CTChart ctChart = chart.getCTChart();
//
// CTPlotArea ctPlotArea = ctChart.getPlotArea();
//
// CTCatAx ctCatAx = ctPlotArea.addNewCatAx();
//
//
// CTTitle title =ctCatAx.addNewTitle();
// CTTx tx = title.addNewTx();
// CTTextBody rich = tx.addNewRich();
// CTTextParagraph para = rich.addNewP();
// CTRegularTextRun r = para.addNewR();
// r.setT("击数(N)次");
//
//
// CTTx txY = title.addNewTx();
// CTTextBody richY = txY.addNewRich();
// richY.addNewBodyPr();
// CTTextParagraph paragraphY= richY.addNewP();
// CTRegularTextRun runY= paragraphY.addNewR();
// runY.setT("含水率WL(L下角标)(%)");
return
chart
;
}
public
static
void
createLine
(
XSSFSheet
sheet
,
ChartPosition
chartPosition
,
LineChart
lineChart
)
{
List
<
Object
>
xAxisList
=
lineChart
.
getxAxisList
();
String
chartTitle
=
lineChart
.
getChartTitle
();
XSSFChart
chart
=
createDrawingPatriarch
(
sheet
,
chartPosition
,
chartTitle
);
//图例位置
XDDFChartLegend
legend
=
chart
.
getOrAddLegend
();
legend
.
setPosition
(
LegendPosition
.
TOP
);
//分类轴标(X轴),标题位置
XDDFCategoryAxis
bottomAxis
=
chart
.
createCategoryAxis
(
AxisPosition
.
BOTTOM
);
bottomAxis
.
setTitle
(
"啊啊啊"
);
//值(Y轴)轴,标题位置
XDDFValueAxis
leftAxis
=
chart
.
createValueAxis
(
AxisPosition
.
LEFT
);
leftAxis
.
setTitle
(
"YYDDWERD"
);
//LINE:折线图,
XDDFLineChartData
data
=
(
XDDFLineChartData
)
chart
.
createData
(
ChartTypes
.
LINE
,
bottomAxis
,
leftAxis
);
XDDFCategoryDataSource
countries
=
XDDFDataSourcesFactory
.
fromArray
(
Arrays
.
copyOf
(
xAxisList
.
toArray
(),
xAxisList
.
toArray
().
length
,
String
[].
class
));
//绘制
chart
.
plot
(
data
);
}
}
src/main/java/com/patzn/cloud/service/lims/gideon/utils/DrawXlsxUtil.java
0 → 100644
View file @
2e72f7d9
package
com
.
patzn
.
cloud
.
service
.
lims
.
gideon
.
utils
;
import
java.io.FileOutputStream
;
import
org.apache.poi.ss.usermodel.Cell
;
import
org.apache.poi.ss.usermodel.Row
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
org.apache.poi.xddf.usermodel.*
;
import
org.apache.poi.xddf.usermodel.chart.*
;
import
org.apache.poi.xssf.usermodel.XSSFChart
;
import
org.apache.poi.xssf.usermodel.XSSFClientAnchor
;
import
org.apache.poi.xssf.usermodel.XSSFDrawing
;
import
org.apache.poi.xssf.usermodel.XSSFSheet
;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook
;
public
class
DrawXlsxUtil
{
/**
* 根据sheet数据画图(单序列)
* caution:文件打开关闭由外部操作
*
* @param distSheet 目标sheet表(画图的表)
* @param anchorPosition 画板位置
* @param chartTitle 图名称
* @param xAxisTitle x轴标识
* @param yAxisTitle y轴标识
* @param xAxisDataRangeAddress x轴数据位置(根据sheet获取)
* @param yAxisDataRangeAddress y轴数据位置
* @param chartType 图样式:暂支持折线、条形
* @param color 颜色
*/
public
static
void
createDataChart
(
XSSFSheet
distSheet
,
AnchorPosition
anchorPosition
,
String
chartTitle
,
String
xAxisTitle
,
String
yAxisTitle
,
CellRangeAddress
xAxisDataRangeAddress
,
CellRangeAddress
yAxisDataRangeAddress
,
ChartTypes
chartType
,
PresetColor
color
)
{
if
(!(
ChartTypes
.
BAR
.
equals
(
chartType
)
||
ChartTypes
.
LINE
.
equals
(
chartType
)))
return
;
//Create a panel to draw
XSSFDrawing
drawing
=
distSheet
.
createDrawingPatriarch
();
XSSFClientAnchor
anchor
=
drawing
.
createAnchor
(
0
,
0
,
0
,
0
,
anchorPosition
.
getCol1Index
(),
anchorPosition
.
getRow1Index
(),
anchorPosition
.
getCol2Index
(),
anchorPosition
.
getRow2Index
());
XSSFChart
chart
=
drawing
.
createChart
(
anchor
);
// Use a category axis for the bottom axis.
XDDFCategoryAxis
bottomAxis
=
chart
.
createCategoryAxis
(
AxisPosition
.
BOTTOM
);
chart
.
setTitleText
(
chartTitle
);
bottomAxis
.
setTitle
(
xAxisTitle
);
XDDFValueAxis
leftAxis
=
chart
.
createValueAxis
(
AxisPosition
.
LEFT
);
leftAxis
.
setTitle
(
yAxisTitle
);
leftAxis
.
setCrosses
(
AxisCrosses
.
AUTO_ZERO
);
leftAxis
.
setCrossBetween
(
AxisCrossBetween
.
BETWEEN
);
XDDFCategoryDataSource
xs
=
XDDFDataSourcesFactory
.
fromStringCellRange
(
distSheet
,
xAxisDataRangeAddress
);
XDDFNumericalDataSource
ys1
=
XDDFDataSourcesFactory
.
fromNumericCellRange
(
distSheet
,
yAxisDataRangeAddress
);
XDDFChartData
data
=
chart
.
createData
(
chartType
,
bottomAxis
,
leftAxis
);
XDDFChartData
.
Series
series1
=
data
.
addSeries
(
xs
,
ys1
);
//line
if
(
data
instanceof
XDDFLineChartData
)
{
XDDFLineChartData
.
Series
series
=
(
XDDFLineChartData
.
Series
)
series1
;
series
.
setSmooth
(
false
);
series
.
setMarkerStyle
(
MarkerStyle
.
NONE
);
}
//bar
if
(
data
instanceof
XDDFBarChartData
)
{
// in order to transform a bar chart into a column chart, you just need to change the bar direction
XDDFBarChartData
bar
=
(
XDDFBarChartData
)
data
;
bar
.
setBarDirection
(
BarDirection
.
COL
);
}
//don't delete the following line
series1
.
setTitle
(
"picture"
,
null
);
chart
.
plot
(
data
);
solidFillSeries
(
data
,
0
,
color
);
}
/**
* 设置图属性
*
* @param data 待画的数据
* @param index 数据序列编号 从0开始
* @param color 颜色
*/
private
static
void
solidFillSeries
(
XDDFChartData
data
,
int
index
,
PresetColor
color
)
{
XDDFSolidFillProperties
fill
=
new
XDDFSolidFillProperties
(
XDDFColor
.
from
(
color
));
XDDFChartData
.
Series
series
=
data
.
getSeries
().
get
(
index
);
XDDFShapeProperties
properties
=
series
.
getShapeProperties
();
if
(
properties
==
null
)
properties
=
new
XDDFShapeProperties
();
//line
if
(
data
instanceof
XDDFLineChartData
)
{
XDDFLineProperties
line
=
new
XDDFLineProperties
();
line
.
setFillProperties
(
fill
);
properties
.
setLineProperties
(
line
);
}
//bar
if
(
data
instanceof
XDDFBarChartData
)
properties
.
setFillProperties
(
fill
);
series
.
setShapeProperties
(
properties
);
}
public
static
void
productZheLine
(
XSSFSheet
sheet
,
AnchorPosition
anchorPosition
,
CellRangeAddress
xAddress
,
CellRangeAddress
yAddress
){
//创建一个画布
}
/**
* 画折线图调用参考
*
* @throws Exception
*/
/**
* 设置画板在sheet中的位置
*/
public
static
class
AnchorPosition
{
private
int
col1Index
;
//起始位置
private
int
row1Index
;
private
int
col2Index
;
//结束位置
private
int
row2Index
;
private
String
title
;
private
String
xTitle
;
private
String
yTitle
;
public
AnchorPosition
(
int
col1Index
,
int
row1Index
,
int
col2Index
,
int
row2Index
,
String
title
,
String
xTitle
,
String
yTitle
)
{
this
.
col1Index
=
col1Index
;
this
.
row1Index
=
row1Index
;
this
.
col2Index
=
col2Index
;
this
.
row2Index
=
row2Index
;
this
.
title
=
title
;
this
.
xTitle
=
xTitle
;
this
.
yTitle
=
yTitle
;
}
public
String
getTitle
()
{
return
title
;
}
public
void
setTitle
(
String
title
)
{
this
.
title
=
title
;
}
public
String
getxTitle
()
{
return
xTitle
;
}
public
void
setxTitle
(
String
xTitle
)
{
this
.
xTitle
=
xTitle
;
}
public
String
getyTitle
()
{
return
yTitle
;
}
public
void
setyTitle
(
String
yTitle
)
{
this
.
yTitle
=
yTitle
;
}
public
int
getCol1Index
()
{
return
col1Index
;
}
public
void
setCol1Index
(
int
col1Index
)
{
this
.
col1Index
=
col1Index
;
}
public
int
getRow1Index
()
{
return
row1Index
;
}
public
void
setRow1Index
(
int
row1Index
)
{
this
.
row1Index
=
row1Index
;
}
public
int
getCol2Index
()
{
return
col2Index
;
}
public
void
setCol2Index
(
int
col2Index
)
{
this
.
col2Index
=
col2Index
;
}
public
int
getRow2Index
()
{
return
row2Index
;
}
public
void
setRow2Index
(
int
row2Index
)
{
this
.
row2Index
=
row2Index
;
}
}
}
\ No newline at end of file
src/main/java/com/patzn/cloud/service/lims/rcp/NettyServer.java
View file @
2e72f7d9
...
@@ -14,9 +14,13 @@ import io.netty.channel.EventLoopGroup;
...
@@ -14,9 +14,13 @@ import io.netty.channel.EventLoopGroup;
import
io.netty.channel.nio.NioEventLoopGroup
;
import
io.netty.channel.nio.NioEventLoopGroup
;
import
io.netty.channel.socket.SocketChannel
;
import
io.netty.channel.socket.SocketChannel
;
import
io.netty.channel.socket.nio.NioServerSocketChannel
;
import
io.netty.channel.socket.nio.NioServerSocketChannel
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
NettyServer
{
public
class
NettyServer
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
NettyServer
.
class
);
public
void
bind
(
int
port
)
throws
Exception
{
public
void
bind
(
int
port
)
throws
Exception
{
EventLoopGroup
bossGroup
=
new
NioEventLoopGroup
();
//bossGroup就是parentGroup,是负责处理TCP/IP连接的
EventLoopGroup
bossGroup
=
new
NioEventLoopGroup
();
//bossGroup就是parentGroup,是负责处理TCP/IP连接的
...
@@ -40,8 +44,10 @@ public class NettyServer {
...
@@ -40,8 +44,10 @@ public class NettyServer {
ChannelFuture
future
=
sb
.
bind
(
port
).
sync
();
ChannelFuture
future
=
sb
.
bind
(
port
).
sync
();
if
(
future
.
isSuccess
())
{
if
(
future
.
isSuccess
())
{
logger
.
error
(
"NettyServer服务端启动成功"
);
System
.
out
.
println
(
"服务端启动成功"
);
System
.
out
.
println
(
"服务端启动成功"
);
}
else
{
}
else
{
logger
.
error
(
"NettyServer服务端启动失败"
);
System
.
out
.
println
(
"服务端启动失败"
);
System
.
out
.
println
(
"服务端启动失败"
);
future
.
cause
().
printStackTrace
();
future
.
cause
().
printStackTrace
();
bossGroup
.
shutdownGracefully
();
//关闭线程组
bossGroup
.
shutdownGracefully
();
//关闭线程组
...
...
src/main/java/com/patzn/cloud/service/lims/rcp/Runner.java
View file @
2e72f7d9
...
@@ -20,6 +20,8 @@ public class Runner implements InitializingBean {
...
@@ -20,6 +20,8 @@ public class Runner implements InitializingBean {
@Override
@Override
public
void
afterPropertiesSet
()
{
public
void
afterPropertiesSet
()
{
logger
.
error
(
"天平端口开始启用--------------------"
);
pool
.
execute
(()
->
{
pool
.
execute
(()
->
{
try
{
try
{
try
{
try
{
...
...
src/main/java/com/patzn/cloud/service/lims/soil/controller/SoilStatisticsController.java
View file @
2e72f7d9
...
@@ -174,7 +174,7 @@ public class SoilStatisticsController extends ServiceController {
...
@@ -174,7 +174,7 @@ public class SoilStatisticsController extends ServiceController {
}
}
@ApiOperation
(
value
=
"
地区样品
查询"
,
notes
=
"地区样品查询"
)
@ApiOperation
(
value
=
"
工程项目
查询"
,
notes
=
"地区样品查询"
)
@ApiImplicitParams
({
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
RestConstants
.
PAGE_PAGE
,
value
=
"请求数据的页码"
,
required
=
true
,
paramType
=
"query"
,
dataType
=
"int"
),
@ApiImplicitParam
(
name
=
RestConstants
.
PAGE_PAGE
,
value
=
"请求数据的页码"
,
required
=
true
,
paramType
=
"query"
,
dataType
=
"int"
),
@ApiImplicitParam
(
name
=
RestConstants
.
PAGE_ROWS
,
value
=
"每页条数"
,
required
=
true
,
paramType
=
"query"
,
dataType
=
"int"
),
@ApiImplicitParam
(
name
=
RestConstants
.
PAGE_ROWS
,
value
=
"每页条数"
,
required
=
true
,
paramType
=
"query"
,
dataType
=
"int"
),
...
...
src/main/java/com/patzn/cloud/service/lims/soil/service/impl/SoilEntrustServiceImpl.java
View file @
2e72f7d9
...
@@ -1528,10 +1528,37 @@ public class SoilEntrustServiceImpl extends BaseServiceImpl<SoilEntrustMapper, S
...
@@ -1528,10 +1528,37 @@ public class SoilEntrustServiceImpl extends BaseServiceImpl<SoilEntrustMapper, S
Map
<
String
,
List
<
String
>>
mapItemName
=
new
HashMap
<>();
Map
<
String
,
List
<
String
>>
mapItemName
=
new
HashMap
<>();
Map
<
String
,
Integer
>
mapItemCount
=
new
HashMap
<>();
Map
<
String
,
Integer
>
mapItemCount
=
new
HashMap
<>();
Map
<
String
,
Map
<
String
,
Integer
>>
itemDetailMap
=
new
HashMap
<>();
for
(
SoilExperimentVO
vo
:
experimentVOList
)
{
for
(
SoilExperimentVO
vo
:
experimentVOList
)
{
if
(
null
==
vo
.
getItemCount
()){
if
(
null
==
vo
.
getItemCount
()){
vo
.
setItemCount
(
0
);
vo
.
setItemCount
(
0
);
}
}
Map
<
String
,
Integer
>
projectItemMap
=
itemDetailMap
.
get
(
vo
.
getProjectName
());
if
(
null
==
projectItemMap
){
projectItemMap
=
new
HashMap
<>();
}
Integer
numItem
=
projectItemMap
.
get
(
vo
.
getName
());
if
(
numItem
==
null
)
{
numItem
=
vo
.
getItemCount
();
}
else
{
numItem
=
numItem
+
vo
.
getItemCount
();
}
projectItemMap
.
put
(
vo
.
getName
(),
numItem
);
itemDetailMap
.
put
(
vo
.
getProjectName
(),
projectItemMap
);
if
(
mapItemName
.
containsKey
(
vo
.
getProjectName
())){
if
(
mapItemName
.
containsKey
(
vo
.
getProjectName
())){
List
<
String
>
nameList
=
mapItemName
.
get
(
vo
.
getProjectName
());
List
<
String
>
nameList
=
mapItemName
.
get
(
vo
.
getProjectName
());
nameList
.
add
(
vo
.
getName
());
nameList
.
add
(
vo
.
getName
());
...
@@ -1557,6 +1584,7 @@ public class SoilEntrustServiceImpl extends BaseServiceImpl<SoilEntrustMapper, S
...
@@ -1557,6 +1584,7 @@ public class SoilEntrustServiceImpl extends BaseServiceImpl<SoilEntrustMapper, S
}
}
for
(
SoilEntrustVO
vo
:
voList
)
{
for
(
SoilEntrustVO
vo
:
voList
)
{
List
<
String
>
nameList
=
mapItemName
.
get
(
vo
.
getProjectName
());
List
<
String
>
nameList
=
mapItemName
.
get
(
vo
.
getProjectName
());
Integer
num
=
mapItemCount
.
get
(
vo
.
getProjectName
());
Integer
num
=
mapItemCount
.
get
(
vo
.
getProjectName
());
...
@@ -1564,6 +1592,21 @@ public class SoilEntrustServiceImpl extends BaseServiceImpl<SoilEntrustMapper, S
...
@@ -1564,6 +1592,21 @@ public class SoilEntrustServiceImpl extends BaseServiceImpl<SoilEntrustMapper, S
vo
.
setItemNames
(
com
.
patzn
.
cloud
.
service
.
lims
.
common
.
StringHandleUtils
.
join
(
nameList
));
vo
.
setItemNames
(
com
.
patzn
.
cloud
.
service
.
lims
.
common
.
StringHandleUtils
.
join
(
nameList
));
}
}
vo
.
setNum
(
num
);
vo
.
setNum
(
num
);
Map
<
String
,
Integer
>
itemNumMyMap
=
itemDetailMap
.
get
(
vo
.
getProjectName
());
if
(
null
==
itemNumMyMap
){
continue
;
}
List
<
SoilExperimentVO
>
soilExperimentVOSList
=
new
ArrayList
<>();
for
(
Map
.
Entry
<
String
,
Integer
>
entry
:
itemNumMyMap
.
entrySet
())
{
SoilExperimentVO
experimentVO
=
new
SoilExperimentVO
();
experimentVO
.
setName
(
entry
.
getKey
());
experimentVO
.
setItemCount
(
entry
.
getValue
());
soilExperimentVOSList
.
add
(
experimentVO
);
}
vo
.
setExperimentVOList
(
soilExperimentVOSList
);
}
}
return
page
.
setRecords
(
voList
);
return
page
.
setRecords
(
voList
);
...
...
src/main/java/com/patzn/cloud/service/lims/soil/service/impl/SoilExperimentServiceImpl.java
View file @
2e72f7d9
...
@@ -27,6 +27,8 @@ import com.patzn.cloud.service.lims.collect.core.CollectDataType;
...
@@ -27,6 +27,8 @@ import com.patzn.cloud.service.lims.collect.core.CollectDataType;
import
com.patzn.cloud.service.lims.common.*
;
import
com.patzn.cloud.service.lims.common.*
;
import
com.patzn.cloud.service.lims.common.service.IExportService
;
import
com.patzn.cloud.service.lims.common.service.IExportService
;
import
com.patzn.cloud.service.lims.common.service.ILmsMsgService
;
import
com.patzn.cloud.service.lims.common.service.ILmsMsgService
;
import
com.patzn.cloud.service.lims.gideon.utils.ApachePoiLineChart4
;
import
com.patzn.cloud.service.lims.gideon.utils.DrawXlsxUtil
;
import
com.patzn.cloud.service.lims.soil.service.*
;
import
com.patzn.cloud.service.lims.soil.service.*
;
import
com.patzn.cloud.service.soil.dto.SoilExperimentQueryDTO
;
import
com.patzn.cloud.service.soil.dto.SoilExperimentQueryDTO
;
import
com.patzn.cloud.service.soil.entity.*
;
import
com.patzn.cloud.service.soil.entity.*
;
...
@@ -43,6 +45,8 @@ import org.apache.commons.collections4.ListUtils;
...
@@ -43,6 +45,8 @@ import org.apache.commons.collections4.ListUtils;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.poi.ss.usermodel.*
;
import
org.apache.poi.ss.usermodel.*
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
org.apache.poi.xddf.usermodel.PresetColor
;
import
org.apache.poi.xddf.usermodel.chart.ChartTypes
;
import
org.apache.poi.xssf.usermodel.*
;
import
org.apache.poi.xssf.usermodel.*
;
import
org.openxmlformats.schemas.drawingml.x2006.chart.*
;
import
org.openxmlformats.schemas.drawingml.x2006.chart.*
;
import
org.openxmlformats.schemas.drawingml.x2006.main.*
;
import
org.openxmlformats.schemas.drawingml.x2006.main.*
;
...
@@ -961,6 +965,16 @@ public class SoilExperimentServiceImpl extends BaseServiceImpl<SoilExperimentMap
...
@@ -961,6 +965,16 @@ public class SoilExperimentServiceImpl extends BaseServiceImpl<SoilExperimentMap
int
sheetNum
=
xssfWorkbook
.
getNumberOfSheets
();
int
sheetNum
=
xssfWorkbook
.
getNumberOfSheets
();
boolean
keliJIa
=
"颗粒分析实验(甲种)"
.
equals
(
template
.
getName
());
if
(
keliJIa
){
//='颗粒分析试验(密度计法)'!$S$3:$T$22
// GenerateChartKeli(xssfSheet,"'"+xssfSheet.getSheetName()+"'!$S$"+3+":"+"$S$"+22,"'"+xssfSheet.getSheetName()+"'!$T$"+3+":$T$"+22);
DrawXlsxUtil
.
AnchorPosition
position
=
new
DrawXlsxUtil
.
AnchorPosition
(
21
,
2
,
28
,
8
,
"颗粒大小分布曲线"
,
"颗粒大小(mm)"
,
"小于某直径之百分数(%)"
);
ApachePoiLineChart4
.
productZhexian
(
xssfSheet
,
position
);
}
for
(
SoilExperimentVO
vo:
voList
)
{
for
(
SoilExperimentVO
vo:
voList
)
{
if
(
index
==
0
){
if
(
index
==
0
){
index
++;
index
++;
...
@@ -969,6 +983,12 @@ public class SoilExperimentServiceImpl extends BaseServiceImpl<SoilExperimentMap
...
@@ -969,6 +983,12 @@ public class SoilExperimentServiceImpl extends BaseServiceImpl<SoilExperimentMap
continue
;
continue
;
}
}
XSSFSheet
sheet
=
xssfWorkbook
.
cloneSheet
(
0
);
XSSFSheet
sheet
=
xssfWorkbook
.
cloneSheet
(
0
);
if
(
keliJIa
){
//GenerateChartKeli(sheet,"'界限含水率 (碟式液限仪多点法)'!$D$"+3+":"+"$D$"+5,"'界限含水率 (碟式液限仪多点法)'!$J$"+3+":$J$"+5);
// GenerateChartKeli(sheet,"'"+sheet.getSheetName()+"'!$S$"+3+":"+"$S$"+22,"'"+sheet.getSheetName()+"'!$T$"+3+":$T$"+22);
DrawXlsxUtil
.
AnchorPosition
position
=
new
DrawXlsxUtil
.
AnchorPosition
(
21
,
2
,
28
,
8
,
"颗粒大小分布曲线"
,
"颗粒大小(mm)"
,
"小于某直径之百分数(%)"
);
ApachePoiLineChart4
.
productZhexian
(
sheet
,
position
);
}
index
++;
index
++;
}
}
...
@@ -1379,6 +1399,114 @@ public class SoilExperimentServiceImpl extends BaseServiceImpl<SoilExperimentMap
...
@@ -1379,6 +1399,114 @@ public class SoilExperimentServiceImpl extends BaseServiceImpl<SoilExperimentMap
}
}
public
void
GenerateChartKeli
(
XSSFSheet
sheet
,
String
xValue
,
String
yValue
)
{
XSSFDrawing
drawing
=
sheet
.
createDrawingPatriarch
();
ClientAnchor
anchor
=
drawing
.
createAnchor
(
100
,
3
,
100
,
100
,
21
,
1
,
27
,
8
);
XSSFChart
chart
=
drawing
.
createChart
(
anchor
);
chart
.
setTitleText
(
"颗粒大小分布曲线"
);
chart
.
setAutoTitleDeleted
(
false
);
CTChart
ctChart
=
chart
.
getCTChart
();
ctChart
.
addNewPlotVisOnly
().
setVal
(
true
);
ctChart
.
addNewDispBlanksAs
().
setVal
(
STDispBlanksAs
.
GAP
);
ctChart
.
addNewShowDLblsOverMax
().
setVal
(
false
);
CTPlotArea
ctPlotArea
=
ctChart
.
getPlotArea
();
CTScatterChart
scatterChart
=
ctPlotArea
.
addNewScatterChart
();
scatterChart
.
addNewScatterStyle
().
setVal
(
STScatterStyle
.
LINE_MARKER
);
scatterChart
.
addNewVaryColors
().
setVal
(
false
);
scatterChart
.
addNewAxId
().
setVal
(
123456
);
scatterChart
.
addNewAxId
().
setVal
(
123457
);
CTCatAx
ctCatAx
=
ctPlotArea
.
addNewCatAx
();
ctCatAx
.
addNewAxId
().
setVal
(
123456
);
CTScaling
ctScaling
=
ctCatAx
.
addNewScaling
();
ctScaling
.
addNewOrientation
().
setVal
(
STOrientation
.
MIN_MAX
);
ctCatAx
.
addNewDelete
().
setVal
(
false
);
ctCatAx
.
addNewAxPos
().
setVal
(
STAxPos
.
B
);
ctCatAx
.
addNewCrossAx
().
setVal
(
123457
);
ctCatAx
.
addNewTickLblPos
().
setVal
(
STTickLblPos
.
NEXT_TO
);
CTTitle
title
=
ctCatAx
.
addNewTitle
();
CTTx
tx
=
title
.
addNewTx
();
CTTextBody
rich
=
tx
.
addNewRich
();
rich
.
addNewBodyPr
();
// body properties must exist, but can be empty
CTTextParagraph
para
=
rich
.
addNewP
();
CTRegularTextRun
r
=
para
.
addNewR
();
r
.
setT
(
"颗粒大小(mm)"
);
ctCatAx
.
setTitle
(
title
);
CTValAx
ctValAx
=
ctPlotArea
.
addNewValAx
();
ctValAx
.
addNewAxId
().
setVal
(
123457
);
CTScaling
ctScaling1
=
ctValAx
.
addNewScaling
();
ctScaling1
.
addNewOrientation
().
setVal
(
STOrientation
.
MIN_MAX
);
ctValAx
.
addNewDelete
().
setVal
(
false
);
ctValAx
.
addNewAxPos
().
setVal
(
STAxPos
.
B
);
ctValAx
.
addNewCrossAx
().
setVal
(
123456
);
CTTitle
ctTitleY
=
ctValAx
.
addNewTitle
();
CTTx
txY
=
ctTitleY
.
addNewTx
();
CTTextBody
richY
=
txY
.
addNewRich
();
richY
.
addNewBodyPr
();
CTTextParagraph
paragraphY
=
richY
.
addNewP
();
CTRegularTextRun
runY
=
paragraphY
.
addNewR
();
runY
.
setT
(
"小于某直径之百分数(%)"
);
ctValAx
.
setTitle
(
ctTitleY
);
CTShapeProperties
ctShapeProperties
=
ctValAx
.
addNewMajorGridlines
().
addNewSpPr
();
CTLineProperties
ctLineProperties
=
ctShapeProperties
.
addNewLn
();
ctLineProperties
.
setW
(
9525
);
ctLineProperties
.
setCap
(
STLineCap
.
Enum
.
forInt
(
3
));
ctLineProperties
.
setCmpd
(
STCompoundLine
.
Enum
.
forInt
(
1
));
ctLineProperties
.
setAlgn
(
STPenAlignment
.
Enum
.
forInt
(
1
));
// 不显示Y轴上的坐标刻度线
ctValAx
.
addNewMajorTickMark
().
setVal
(
STTickMark
.
NONE
);
ctValAx
.
addNewMinorTickMark
().
setVal
(
STTickMark
.
NONE
);
ctValAx
.
addNewTickLblPos
().
setVal
(
STTickLblPos
.
NEXT_TO
);
// 设置散点图内的信息
CTScatterSer
ctScatterSer
=
scatterChart
.
addNewSer
();
ctScatterSer
.
addNewIdx
().
setVal
(
0
);
ctScatterSer
.
addNewOrder
().
setVal
(
0
);
// 去掉连接线
ctPlotArea
.
getScatterChartArray
(
0
).
getSerArray
(
0
).
addNewSpPr
().
addNewLn
().
addNewNoFill
();
// 设置散点图各图例的显示
CTDLbls
ctdLbls
=
scatterChart
.
addNewDLbls
();
ctdLbls
.
addNewShowVal
().
setVal
(
true
);
ctdLbls
.
addNewShowLegendKey
().
setVal
(
false
);
ctdLbls
.
addNewShowSerName
().
setVal
(
false
);
ctdLbls
.
addNewShowCatName
().
setVal
(
false
);
ctdLbls
.
addNewShowPercent
().
setVal
(
false
);
ctdLbls
.
addNewShowBubbleSize
().
setVal
(
false
);
// 设置标记的样式
CTMarker
ctMarker
=
ctScatterSer
.
addNewMarker
();
ctMarker
.
addNewSymbol
().
setVal
(
STMarkerStyle
.
Enum
.
forInt
(
3
));
ctMarker
.
addNewSize
().
setVal
((
short
)
5
);
CTShapeProperties
ctShapeProperties1
=
ctMarker
.
addNewSpPr
();
ctShapeProperties1
.
addNewSolidFill
().
addNewSchemeClr
().
setVal
(
STSchemeColorVal
.
Enum
.
forInt
(
5
));
CTLineProperties
ctLineProperties1
=
ctShapeProperties1
.
addNewLn
();
ctLineProperties1
.
setW
(
9525
);
ctLineProperties1
.
addNewSolidFill
().
addNewSchemeClr
().
setVal
(
STSchemeColorVal
.
Enum
.
forInt
(
5
));
CTAxDataSource
ctAxDataSource
=
ctScatterSer
.
addNewXVal
();
CTStrRef
ctStrRef
=
ctAxDataSource
.
addNewStrRef
();
ctStrRef
.
setF
(
xValue
);
CTNumDataSource
ctNumDataSource
=
ctScatterSer
.
addNewYVal
();
CTNumRef
ctNumRef
=
ctNumDataSource
.
addNewNumRef
();
ctNumRef
.
setF
(
yValue
);
}
@Override
@Override
public
SoilExpReport
saveExcelExpReport
(
String
expName
,
Long
entrustId
,
Long
[]
ids
,
Long
templateId
,
Account
account
)
{
public
SoilExpReport
saveExcelExpReport
(
String
expName
,
Long
entrustId
,
Long
[]
ids
,
Long
templateId
,
Account
account
)
{
RestAssert
.
fail
(
ArrayUtils
.
isEmpty
(
ids
),
"请选择试验项目!"
);
RestAssert
.
fail
(
ArrayUtils
.
isEmpty
(
ids
),
"请选择试验项目!"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment