@@ -14,6 +14,7 @@ import com.njcn.product.event.devcie.mapper.PqLineMapper;
import com.njcn.product.event.devcie.pojo.dto.LedgerBaseInfoDTO ;
import com.njcn.product.event.devcie.pojo.dto.PqsDeptDTO ;
import com.njcn.product.event.report.pojo.dto.BjCustomReportDTO ;
import com.njcn.product.event.report.pojo.dto.EventTemplate ;
import com.njcn.product.event.report.pojo.param.ReportExportParam ;
import com.njcn.product.event.report.service.EasyPoiWordExportService ;
import com.njcn.product.event.report.utils.WordTemplate ;
@@ -25,7 +26,13 @@ import com.njcn.product.event.transientes.service.CommGeneralService;
import com.njcn.product.event.transientes.service.MsgEventConfigService ;
import lombok.RequiredArgsConstructor ;
import org.apache.poi.xwpf.usermodel.XWPFDocument ;
import org.apache.poi.xwpf.usermodel.XWPFTable ;
import org.apache.poi.xwpf.usermodel.XWPFTableCell ;
import org.apache.poi.xwpf.usermodel.XWPFTableRow ;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge ;
import org.springframework.beans.factory.annotation.Value ;
import org.springframework.stereotype.Service ;
import org.springframework.util.CollectionUtils ;
import javax.servlet.http.HttpServletResponse ;
import java.util.ArrayList ;
@@ -34,6 +41,7 @@ import java.util.List;
import java.util.Map ;
import java.util.stream.Collectors ;
import java.util.stream.DoubleStream ;
import java.util.stream.Stream ;
/**
* @Author: cdf
@@ -60,9 +68,13 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
private final PqUserLineAssMapper pqUserLineAssMapper ;
private final PqUserLedgerMapper pqUserLedgerMapper ;
private final PqsDicTreeMapper pqsDicTreeMapper ;
private final ObjectMapper mapper = new ObjectMapper ( ) ;
@Value ( " ${business.wordTemplatePath} " )
private String wordTemplatePath ;
@Override
public void test ( HttpServletResponse response , ReportExportParam param ) {
try {
List < Integer > deptIds = commGeneralService . getLineIdsByRedis ( param . getDeptId ( ) ) ;
if ( CollUtil . isEmpty ( deptIds ) ) {
@@ -100,8 +112,32 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
}
List < PqsEventdetail > pqsEventdetailList = pqsEventdetailMapper . selectList ( lambdaQueryWrapper ) ;
List < Map < String , Object > > eventTemplateList = new ArrayList < > ( ) ;
for ( int i = 0 ; i < pqsEventdetailList . size ( ) ; i + + ) {
PqsEventdetail pqsEventdetail = pqsEventdetailList . get ( i ) ;
EventTemplate eventTemplate = new EventTemplate ( ) ;
eventTemplate . setSno ( i + 1 ) ;
eventTemplate . setTimeId ( pqsEventdetail . getTimeid ( ) . format ( DatePattern . NORM_DATETIME_FORMATTER ) + " . " + pqsEventdetail . getMs ( ) ) ;
List < LedgerBaseInfoDTO > baseLineInfo = pqLineMapper . getBaseLineInfo ( Stream . of ( pqsEventdetailList . get ( i ) . getLineid ( ) ) . collect ( Collectors . toList ( ) ) ) ;
eventTemplate . setOrgName ( baseLineInfo . get ( 0 ) . getGdName ( ) ) ;
eventTemplate . setSubName ( baseLineInfo . get ( 0 ) . getStationName ( ) ) ;
eventTemplate . setBusName ( baseLineInfo . get ( 0 ) . getBusBarName ( ) ) ;
eventTemplate . setScale ( pqsDicDataMap . get ( baseLineInfo . get ( 0 ) . getScale ( ) ) . getDicName ( ) ) ;
eventTemplate . setDuration ( String . format ( " %.3f " , pqsEventdetail . getPersisttime ( ) / 1000 ) ) ;
eventTemplate . setResidualVoltage ( String . format ( " %.2f " , pqsEventdetail . getEventvalue ( ) * 100 ) ) ;
eventTemplate . setUserName ( baseLineInfo . get ( 0 ) . getObjName ( ) ) ;
Map < String , Object > eventMap = mapper . convertValue ( eventTemplate , Map . class ) ;
eventTemplateList . add ( eventMap ) ;
}
bjReportDTO . setEvent ( eventTemplateList ) ;
bjReportDTO . setBjTotalEvent ( pqsEventdetailList . size ( ) ) ;
List < Integer > lineIds = pqsEventdetailList . stream ( ) . map ( PqsEventdetail : : getLineid ) . distinct ( ) . collect ( Collectors . toList ( ) ) ;
if ( CollectionUtils . isEmpty ( lineIds ) ) {
//如果lineIds为空添加一个不是监测点的监测点id避免后边查询错误
lineIds . add ( 99999999 ) ;
}
List < LedgerBaseInfoDTO > ledgerBaseInfoDTOList = pqLineMapper . getBaseLedger ( lineIds , null ) ;
long stationCount = ledgerBaseInfoDTOList . stream ( ) . map ( LedgerBaseInfoDTO : : getStationId ) . distinct ( ) . count ( ) ;
bjReportDTO . setTotalEventSubstation ( ( int ) stationCount ) ;
@@ -109,9 +145,9 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
bjReportDTO . setBjTotalBus ( ( int ) busCount ) ;
String busVoltageStr = busVoltageDeal ( ledgerBaseInfoDTOList , pqsDicDataMap ) ;
bjReportDTO . setStationVoltage ( busVoltageStr ) ;
double min = pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getEventvalue ) . min ( ) . getAsDouble ( ) * 100 ;
double max = pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getEventvalue ) . max ( ) . getAsDouble ( ) * 100 ;
//double容易精度缺失
double min = Math . round ( pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getEventvalue ) . min ( ) . getAsDouble ( ) * 100* 100 ) * 0 . 01d ;
double max = Math . round ( pqsEventdetailList. stream ( ) . mapToDouble ( PqsEventdetail : : getEventvalue ) . max ( ) . getAsDouble ( ) * 100 * 100 ) * 0 . 01d ;
bjReportDTO . setResidualVoltageRange ( min + " %- " + max + " % " ) ;
double minPersisTime = pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getPersisttime ) . min ( ) . getAsDouble ( ) / 1000 ;
@@ -127,16 +163,161 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
bjReportDTO . setObjTypeList ( treeStr ) ;
bjReportDTO . setAffectedUserCount ( pqUserLedgerPOList . size ( ) ) ;
areaAssemble ( bjReportDTO , param , pqsDicDataMap ) ;
ObjectMapper mapper = new ObjectMapper ( ) ;
Map < String , Object > map = mapper . convertValue ( bjReportDTO , Map . class ) ;
WordTemplate . generateWordDownload ( " t emplate/test.docx" , response , " aa .docx" , map ) ;
WordTemplate . generateWordDownload ( wordT emplatePath + " /test.docx" , response , " 重要敏感用户电压暂降事件监测情况 .docx" , map ) ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
private void areaAssemble ( BjCustomReportDTO bjReportDTO , ReportExportParam param , Map < String , PqsDicData > pqsDicDataMap ) {
List < PqsDeptDTO > pqsDeptsList = pqsDeptsMapper . getDeptList ( param . getDeptList ( ) ) ;
Map < String , String > deptMap = pqsDeptsList . stream ( ) . collect ( Collectors . toMap ( PqsDeptDTO : : getDeptsIndex , PqsDeptDTO : : getDeptsname ) ) ;
List < String > areaContentList = new ArrayList < > ( ) ;
List < Map < String , Object > > eventTemplateList = new ArrayList < > ( ) ;
param . getDeptList ( ) . forEach ( deptId - > {
String deptName = deptMap . get ( deptId ) ;
String areaContent = " " ;
String userContext = " " ;
List < Integer > deptLineIds = commGeneralService . getLineIdsByRedis ( deptId ) ;
if ( CollectionUtils . isEmpty ( deptLineIds ) ) {
areaContent = deptName + " 共监测到电压暂降事件0条 " ;
} else {
LambdaQueryWrapper < PqsEventdetail > lambdaQueryWrapper = new LambdaQueryWrapper < > ( ) ;
lambdaQueryWrapper . in ( PqsEventdetail : : getWavetype , msgEventConfigService . getEventType ( ) )
. gt ( PqsEventdetail : : getPersisttime , msgEventConfigService . getEventDuration ( ) )
. le ( PqsEventdetail : : getEventvalue , msgEventConfigService . getEventValue ( ) )
. between ( PqsEventdetail : : getTimeid , DateUtil . parse ( param . getSearchBeginTime ( ) , DatePattern . NORM_DATETIME_PATTERN ) , DateUtil . parse ( param . getSearchEndTime ( ) , DatePattern . NORM_DATETIME_PATTERN ) ) ;
if ( deptLineIds . size ( ) > 1000 ) {
List < List < Integer > > listList = CollUtil . split ( deptLineIds , 1000 ) ;
lambdaQueryWrapper . and ( w - > {
w . or ( i - > {
for ( List < Integer > ids : listList ) {
i . in ( PqsEventdetail : : getLineid , ids ) ;
}
} ) ;
} ) ;
} else {
lambdaQueryWrapper . in ( PqsEventdetail : : getLineid , deptLineIds ) ;
}
List < PqsEventdetail > pqsEventdetailList = pqsEventdetailMapper . selectList ( lambdaQueryWrapper ) ;
if ( CollectionUtils . isEmpty ( pqsEventdetailList ) ) {
areaContent = deptName + " 共监测到电压暂降事件0条 " ;
} else {
Integer eveCount = pqsEventdetailList . size ( ) ;
List < Integer > lineIds = pqsEventdetailList . stream ( ) . map ( PqsEventdetail : : getLineid ) . distinct ( ) . collect ( Collectors . toList ( ) ) ;
List < LedgerBaseInfoDTO > ledgerBaseInfoDTOList = pqLineMapper . getBaseLedger ( lineIds , null ) ;
long stationCount = ledgerBaseInfoDTOList . stream ( ) . map ( LedgerBaseInfoDTO : : getStationId ) . distinct ( ) . count ( ) ;
long busCount = ledgerBaseInfoDTOList . stream ( ) . map ( LedgerBaseInfoDTO : : getBusBarId ) . distinct ( ) . count ( ) ;
String stationStr = stationVoltageDeal ( ledgerBaseInfoDTOList , pqsDicDataMap ) ;
String areabusVoltageDeal = areabusVoltageDeal ( ledgerBaseInfoDTOList , pqsDicDataMap ) ;
double min = Math . round ( pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getEventvalue ) . min ( ) . getAsDouble ( ) * 100 * 100 ) * 0 . 01d ;
double max = Math . round ( pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getEventvalue ) . max ( ) . getAsDouble ( ) * 100 * 100 ) * 0 . 01d ;
String residualVoltage = min + " %- " + max + " % " ;
double minPersisTime = pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getPersisttime ) . min ( ) . getAsDouble ( ) / 1000 ;
double maxPersisTime = pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getPersisttime ) . max ( ) . getAsDouble ( ) / 1000 ;
String duration = minPersisTime + " s- " + maxPersisTime + " s " ;
String temp = " %s共监测到电压暂降事件%s条, 涉及%s座变电站, %s条母线, 其中: %s, 造成%s发生电压暂降, 残余电压范围为%s, 持续时间范围为%s。 " ;
areaContent = String . format ( temp , deptName , eveCount , stationCount , busCount , stationStr , areabusVoltageDeal , residualVoltage , duration ) ;
if ( ! CollectionUtils . isEmpty ( lineIds ) ) {
List < PqUserLineAssPO > pqUserLineAssPOS = pqUserLineAssMapper . selectList ( new LambdaQueryWrapper < PqUserLineAssPO > ( ) . in ( PqUserLineAssPO : : getLineIndex , lineIds ) ) ;
List < String > userIds = pqUserLineAssPOS . stream ( ) . map ( PqUserLineAssPO : : getUserIndex ) . distinct ( ) . collect ( Collectors . toList ( ) ) ;
LambdaQueryWrapper < PqUserLedgerPO > pqUserLedgerPOLambdaQueryWrapper = new LambdaQueryWrapper < PqUserLedgerPO > ( ) ;
pqUserLedgerPOLambdaQueryWrapper . in ( PqUserLedgerPO : : getId , userIds ) . eq ( PqUserLedgerPO : : getIsShow , 1 ) ;
List < PqUserLedgerPO > pqUserLedgerPOList = pqUserLedgerMapper . selectList ( pqUserLedgerPOLambdaQueryWrapper ) ;
if ( CollectionUtils . isEmpty ( pqUserLedgerPOList ) ) {
userContext = " 不涉及半导体及重点关注用户。 " ;
} else {
String companyName = pqUserLedgerPOList . stream ( ) . map ( PqUserLedgerPO : : getCustomerName ) . collect ( Collectors . joining ( " 、 " , " ( " , " ) " ) ) ;
userContext = " 涉及 " + pqUserLedgerPOList . size ( ) + " 家半导体及重点关注用户 " + companyName + " , " ;
//逆推监测点,过滤发生暂降事件
List < String > companyId = pqUserLedgerPOList . stream ( ) . map ( PqUserLedgerPO : : getId ) . collect ( Collectors . toList ( ) ) ;
List < PqUserLineAssPO > pqUserLineAssPOS1 = pqUserLineAssMapper . selectList ( new LambdaQueryWrapper < PqUserLineAssPO > ( ) . in ( PqUserLineAssPO : : getUserIndex , companyId ) ) ;
List < String > companyNameList = pqUserLedgerPOList . stream ( ) . map ( PqUserLedgerPO : : getCustomerName ) . collect ( Collectors . toList ( ) ) ;
List < Integer > companyLineId = pqUserLineAssPOS1 . stream ( ) . map ( PqUserLineAssPO : : getLineIndex ) . collect ( Collectors . toList ( ) ) ;
List < PqsEventdetail > companyevent = pqsEventdetailList . stream ( ) . filter ( pqsEventdetail - > companyLineId . contains ( pqsEventdetail . getLineid ( ) ) ) . collect ( Collectors . toList ( ) ) ;
if ( CollectionUtils . isEmpty ( companyevent ) ) {
userContext = userContext + " 暂未发生暂态事件。 " ;
} else {
for ( int i = 0 ; i < pqsEventdetailList . size ( ) ; i + + ) {
PqsEventdetail pqsEventdetail = pqsEventdetailList . get ( i ) ;
List < LedgerBaseInfoDTO > baseLineInfo = pqLineMapper . getBaseLineInfo ( Stream . of ( pqsEventdetailList . get ( i ) . getLineid ( ) ) . collect ( Collectors . toList ( ) ) ) ;
String [ ] split = baseLineInfo . get ( 0 ) . getObjName ( ) . split ( " ; " ) ;
for ( int i1 = 0 ; i1 < split . length ; i1 + + ) {
if ( companyNameList . contains ( split [ i1 ] ) ) {
EventTemplate eventTemplate = new EventTemplate ( ) ;
eventTemplate . setTimeId ( pqsEventdetail . getTimeid ( ) . format ( DatePattern . NORM_DATETIME_FORMATTER ) + " . " + pqsEventdetail . getMs ( ) ) ;
eventTemplate . setOrgName ( baseLineInfo . get ( 0 ) . getGdName ( ) ) ;
eventTemplate . setSubName ( baseLineInfo . get ( 0 ) . getStationName ( ) ) ;
eventTemplate . setBusName ( baseLineInfo . get ( 0 ) . getBusBarName ( ) ) ;
eventTemplate . setScale ( pqsDicDataMap . get ( baseLineInfo . get ( 0 ) . getScale ( ) ) . getDicName ( ) ) ;
eventTemplate . setDuration ( String . format ( " %.3f " , pqsEventdetail . getPersisttime ( ) / 1000 ) ) ;
eventTemplate . setResidualVoltage ( String . format ( " %.2f " , pqsEventdetail . getEventvalue ( ) * 100 ) ) ;
eventTemplate . setUserName ( split [ i1 ] ) ;
Map < String , Object > eventMap = mapper . convertValue ( eventTemplate , Map . class ) ;
eventTemplateList . add ( eventMap ) ;
}
}
}
Integer companyEveCount = companyevent . size ( ) ;
List < Integer > companyLineIds = companyevent . stream ( ) . map ( PqsEventdetail : : getLineid ) . distinct ( ) . collect ( Collectors . toList ( ) ) ;
List < LedgerBaseInfoDTO > companyLedgerBaseInfoDTOList = pqLineMapper . getBaseLedger ( companyLineIds , null ) ;
long companyStationCount = companyLedgerBaseInfoDTOList . stream ( ) . map ( LedgerBaseInfoDTO : : getStationId ) . distinct ( ) . count ( ) ;
long companyBusCount = companyLedgerBaseInfoDTOList . stream ( ) . map ( LedgerBaseInfoDTO : : getBusBarId ) . distinct ( ) . count ( ) ;
String companyStationStr = stationVoltageDeal ( companyLedgerBaseInfoDTOList , pqsDicDataMap ) ;
String companyAreabusVoltageDeal = areabusVoltageDeal ( companyLedgerBaseInfoDTOList , pqsDicDataMap ) ;
double companyMin = Math . round ( pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getEventvalue ) . min ( ) . getAsDouble ( ) * 100 * 100 ) * 0 . 01d ;
double companyMax = Math . round ( pqsEventdetailList . stream ( ) . mapToDouble ( PqsEventdetail : : getEventvalue ) . max ( ) . getAsDouble ( ) * 100 * 100 ) * 0 . 01d ;
String companyResidualVoltage = companyMin + " %- " + companyMax + " % " ;
double companyMinPersisTime = companyevent . stream ( ) . mapToDouble ( PqsEventdetail : : getPersisttime ) . min ( ) . getAsDouble ( ) / 1000 ;
double companyMaxPersisTime = companyevent . stream ( ) . mapToDouble ( PqsEventdetail : : getPersisttime ) . max ( ) . getAsDouble ( ) / 1000 ;
String companyDuration = companyMinPersisTime + " s- " + companyMaxPersisTime + " s " ;
String companyTemp = " 电压暂降事件%s条, 变电站%s座, 母线%s条, 其中: %s, 造成%s发生电压暂降, 残余电压范围为%s, 持续时间范围为%s。 " ;
userContext = userContext + String . format ( companyTemp , companyEveCount , companyStationCount , companyBusCount , companyStationStr , companyAreabusVoltageDeal , companyResidualVoltage , companyDuration ) ;
}
}
} else {
userContext = " 不涉及半导体及重点关注用户。 " ;
}
}
}
areaContent = areaContent + userContext ;
areaContentList . add ( areaContent ) ;
} ) ;
// 或者直接使用 \n
String result2 = String . join ( " \ n " , areaContentList ) ;
bjReportDTO . setAreaContent ( result2 ) ;
bjReportDTO . setCompanyEvent ( eventTemplateList ) ;
}
private void addUserDataToTable ( XWPFDocument document ) {
// 创建表格
// 填充数据到表格(此处为示例代码框架,实际需完善表格创建和数据填充逻辑)
@@ -193,7 +374,7 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
List < LedgerBaseInfoDTO > dtoList = pqLineMapper . getBaseLedger ( temIds , null ) ;
long innerStation = dtoList . stream ( ) . map ( LedgerBaseInfoDTO : : getStationId ) . distinct ( ) . count ( ) ;
long innerBus = dtoList . stream ( ) . map ( LedgerBaseInfoDTO : : getStation Id ) . distinct ( ) . count ( ) ;
long innerBus = dtoList . stream ( ) . map ( LedgerBaseInfoDTO : : getBusBar Id ) . distinct ( ) . count ( ) ;
strBuilderInner . append ( String . valueOf ( innerStation ) ) . append ( " 座,母线 " ) . append ( String . valueOf ( innerBus ) ) . append ( " 条,其中: " ) ;
Map < String , List < LedgerBaseInfoDTO > > scaleInnerMap = dtoList . stream ( ) . collect ( Collectors . groupingBy ( LedgerBaseInfoDTO : : getScale ) ) ;
@@ -210,8 +391,9 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
. collect ( Collectors . joining ( StrUtil . COMMA ) ) ;
strBuilderInner . append ( resultContent ) . append ( " ; " ) ;
temStr . append ( strBuilderInner ) ;
}
bjReportDTO . setAreaInfo ( temStr . toString ( ) ) ;
bjReportDTO . setAreaInfo ( temStr . toString ( ) . substring ( 0 , temStr . length ( ) - 1 ) );
bjReportDTO . setDateFormat ( DateUtil . format ( DateUtil . parse ( param . getSearchBeginTime ( ) ) , DatePattern . NORM_DATE_PATTERN ) ) ;
bjReportDTO . setTotalDevice ( ( int ) devCount ) ;
@@ -236,6 +418,37 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
return result ;
}
private String areabusVoltageDeal ( List < LedgerBaseInfoDTO > ledgerList , Map < String , PqsDicData > pqsDicDataMap ) {
Map < String , List < LedgerBaseInfoDTO > > scaleMap = ledgerList . stream ( ) . collect ( Collectors . groupingBy ( LedgerBaseInfoDTO : : getScale ) ) ;
String result = scaleMap . entrySet ( ) . stream ( )
. map ( entry - > {
String scale = entry . getKey ( ) ;
long busNum = entry . getValue ( ) . stream ( )
. map ( LedgerBaseInfoDTO : : getBusBarId )
. distinct ( )
. count ( ) ;
return busNum + " 条 " + pqsDicDataMap . get ( scale ) . getDicName ( ) + " 母线 " ;
} )
// 用分号连接
. collect ( Collectors . joining ( StrUtil . COMMA ) ) ;
return result ;
}
private String stationVoltageDeal ( List < LedgerBaseInfoDTO > ledgerList , Map < String , PqsDicData > pqsDicDataMap ) {
Map < String , List < LedgerBaseInfoDTO > > scaleMap = ledgerList . stream ( ) . collect ( Collectors . groupingBy ( LedgerBaseInfoDTO : : getScale ) ) ;
String result = scaleMap . entrySet ( ) . stream ( )
. map ( entry - > {
String scale = entry . getKey ( ) ;
long stationNum = entry . getValue ( ) . stream ( )
. map ( LedgerBaseInfoDTO : : getStationId )
. distinct ( )
. count ( ) ;
return pqsDicDataMap . get ( scale ) . getDicName ( ) + " 变电站 " + stationNum + " 座 " ;
} )
// 用分号连接
. collect ( Collectors . joining ( StrUtil . COMMA ) ) ;
return result ;
}
private String userToStr ( Map < String , List < PqUserLedgerPO > > stringListMap , Map < String , PqsDicTreePO > treePOMap ) {
String result = stringListMap . entrySet ( ) . stream ( )
. map ( entry - > {
@@ -250,4 +463,92 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
. collect ( Collectors . joining ( StrUtil . COMMA ) ) ;
return result ;
}
/**
* 手动合并表格单元格
* 合并规则:相邻行中指定列的值相同时进行合并
*/
private void mergeTableCells ( XWPFDocument doc ) {
// 获取文档中的所有表格
List < XWPFTable > tables = doc . getTables ( ) ;
for ( XWPFTable table : tables ) {
int rowCount = table . getNumberOfRows ( ) ;
if ( rowCount < = 1 ) continue ;
// 定义需要合并的列索引(根据你的表格结构调整)
int [ ] mergeColumns = { 0 , 1 } ; // 第1列(姓名)和第2列(班级)需要合并
for ( int colIndex : mergeColumns ) {
mergeVerticalCells ( table , colIndex ) ;
}
}
}
/**
* 垂直合并指定列的相同值单元格
*/
private void mergeVerticalCells ( XWPFTable table , int colIndex ) {
int rowCount = table . getNumberOfRows ( ) ;
int mergeStartRow = - 1 ;
String previousValue = null ;
for ( int i = 0 ; i < rowCount ; i + + ) {
XWPFTableRow row = table . getRow ( i ) ;
if ( row = = null ) continue ;
XWPFTableCell cell = row . getCell ( colIndex ) ;
if ( cell = = null ) continue ;
String currentValue = cell . getText ( ) ;
if ( currentValue . equals ( previousValue ) ) {
// 值相同,继续合并区间
if ( mergeStartRow = = - 1 ) {
mergeStartRow = i - 1 ;
}
// 如果是最后一行,需要执行合并
if ( i = = rowCount - 1 ) {
mergeCells ( table , colIndex , mergeStartRow , i ) ;
}
} else {
// 值不同,合并之前的区间
if ( mergeStartRow ! = - 1 ) {
mergeCells ( table , colIndex , mergeStartRow , i - 1 ) ;
mergeStartRow = - 1 ;
}
previousValue = currentValue ;
}
}
}
/**
* 执行单元格合并
*/
private void mergeCells ( XWPFTable table , int colIndex , int startRow , int endRow ) {
if ( startRow > = endRow ) return ;
for ( int i = startRow ; i < = endRow ; i + + ) {
XWPFTableRow row = table . getRow ( i ) ;
if ( row ! = null ) {
XWPFTableCell cell = row . getCell ( colIndex ) ;
if ( cell ! = null ) {
if ( i = = startRow ) {
// 起始行设置合并属性
cell . getCTTc ( ) . addNewTcPr ( ) . addNewVMerge ( ) . setVal ( STMerge . RESTART ) ;
} else {
// 后续行设置为继续合并
cell . getCTTc ( ) . addNewTcPr ( ) . addNewVMerge ( ) . setVal ( STMerge . CONTINUE ) ;
}
}
}
}
}
public static void main ( String [ ] args ) {
String temp = " 共监测到电压暂降事件%s条, 涉及%s座变电站 " ;
String format = String . format ( temp , 111 , 111 ) ;
System . out . println ( format ) ;
}
}