diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 37d59c6..3cb5b52 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -16,6 +16,11 @@ + + org.apache.poi + poi-ooxml + 5.2.3 + cn.hutool hutool-all diff --git a/ruoyi-admin/src/main/java/com/ruoyi/gysl/controller/BasicInformationController.java b/ruoyi-admin/src/main/java/com/ruoyi/gysl/controller/BasicInformationController.java index e31d2ef..63b37d5 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/gysl/controller/BasicInformationController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/gysl/controller/BasicInformationController.java @@ -2,12 +2,10 @@ package com.ruoyi.gysl.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.poi.ChangeExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.docking.entity.SmartDeclaration; import com.ruoyi.docking.service.SmartDeclarationService; @@ -15,24 +13,20 @@ import com.ruoyi.gysl.entity.*; import com.ruoyi.gysl.entity.request.AuditRequest; import com.ruoyi.gysl.entity.request.BasicInformationPageReq; import com.ruoyi.gysl.entity.response.BasicInformationResponse; -import com.ruoyi.gysl.entity.response.ProjectBuildingExcel; import com.ruoyi.gysl.entity.response.ProjectExcelInfo; import com.ruoyi.gysl.service.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import org.apache.poi.xssf.usermodel.*; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.URLEncoder; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * 基本信息(BasicInformation)表控制层 @@ -45,6 +39,19 @@ import java.util.*; @RequestMapping("/gysl/basicInformation") public class BasicInformationController extends BaseController { + // 1.审核通过之后再审核不要通知 + // 2.项目评价配置和详情那边同步显示 + // 3.换掉项目动态导出模板 + // 6.项目不填项目起止日期导入失败 + // 7.企业端统计项目总数有问题 + // 9.项目基础信息时间查询改了格式 + // 10.添加项目统计页面根据年份查找统计数据 + + // 4.项目汇编管理修改pdf + // 5.月度报告修改 + // 8.企业和政务登录 + + /** * 基本信息 */ @@ -133,7 +140,7 @@ public class BasicInformationController extends BaseController { if (byId.getStatus() != 1) { throw new ServiceException("暂不能提交!"); } - return success(basicInformationService.audit(req, 2)); + return success(basicInformationService.audit(req, 2,byId.getStatus())); } /** @@ -147,7 +154,7 @@ public class BasicInformationController extends BaseController { if (byId.getStatus() == 1) { throw new ServiceException("请等待企业填报!"); } - return success(basicInformationService.audit(req, 3)); + return success(basicInformationService.audit(req, 3,byId.getStatus())); } /** @@ -249,169 +256,15 @@ public class BasicInformationController extends BaseController { } /** - * 动态导出基本信息(基本信息,建筑,规划) + * 导出项目数据 */ - @PreAuthorize("@ss.hasAnyRoles('admin,common')") - @ApiOperation("动态导出基本信息(基本信息,建筑,规划)") +// @PreAuthorize("@ss.hasAnyRoles('admin,common')") + @ApiOperation("导出项目数据") @PostMapping("/exportInfo") - public void exportInfo(HttpServletResponse response, @RequestParam List idList) throws NoSuchFieldException, IOException, IllegalAccessException { - //获取对应的基本信息的列表 - List info = basicInformationService.selectList(idList); - - System.out.println(info); - //excel 第一层单元格 - List yc = new ArrayList<>(); - //excel 第二层单元格 - List ec = new ArrayList<>(); - //excel 第三层单元格 - List sc = new ArrayList<>(); - //项目建筑信息数据所有字段数量 - int sczdData = 0; - //一共有几组厂房,不包括重复 - int cfsl = 0; - //动态存储每个分组对应的字段数量 - Map zdsl = new LinkedHashMap<>(); - Class clazz = ProjectExcelInfo.class; - Class classBuilding = ProjectBuildingExcel.class; - // 遍历除了建筑获取其他字段注解 - for (int i = 0; i < info.size(); i++) { - if (i == 0) { - if(info.get(i).getXmjzxx().isEmpty()){ - throw new ServiceException("请选择有楼栋的项目!"); - } - for (Field field : clazz.getDeclaredFields()) { - Excel excelColumn = field.getAnnotation(Excel.class); - if (excelColumn != null) { - if (yc.contains(excelColumn.group())) { - yc.add(""); - } else { - yc.add(excelColumn.group()); - } - if ("id".equals(excelColumn.name())) { - sc.add(""); - } else { - sc.add(excelColumn.name()); - } - if (!Objects.equals(excelColumn.group(), "序号")) { - zdsl.merge(excelColumn.group(), 1, Integer::sum); - } - ec.add(""); - } - } - } - for (ProjectBuildingExcel xmjzxx : info.get(i).getXmjzxx()) { - switch (xmjzxx.getFloor()) { - case 1: - if (!ec.contains("一层厂房")) { - ec.add("一层厂房"); - cfsl += 1; - } - break; - case 2: - if (!ec.contains("双层厂房")) { - ec.add("双层厂房"); - cfsl += 1; - } - break; - case 3: - if (!ec.contains("三层厂房")) { - ec.add("三层厂房"); - cfsl += 1; - } - break; - case 4: - if (!ec.contains("四层厂房")) { - ec.add("四层厂房"); - cfsl += 1; - } - break; - case 5: - if (!ec.contains("五层厂房")) { - ec.add("五层厂房"); - cfsl += 1; - } - break; - default: - if (!ec.contains("六层及以上厂房")) { - ec.add("六层及以上厂房"); - cfsl += 1; - } - } - for (Field field : classBuilding.getDeclaredFields()) { - Excel excelColumn = field.getAnnotation(Excel.class); - if (excelColumn != null) { - if (!yc.contains("项目建筑信息")) { - yc.add("项目建筑信息"); - } else { - yc.add(""); - } - ec.add(""); - sc.add(excelColumn.name()); - sczdData += 1; - } - } - ec.remove(ec.size() - 1); - } - } - //=======================sheet处理 - // 第一步,创建一个Workbook,对应一个Excel文件 - XSSFWorkbook wb = new XSSFWorkbook(); - // 第二步,在Workbook中添加一个sheet,对应Excel文件中的sheet - XSSFSheet sheet = wb.createSheet("sheet"); - // 第三步,设置样式以及字体样式 - XSSFCellStyle titleStyle = ChangeExcelUtil.createTitleCellStyle(wb); - XSSFCellStyle headerStyle = ChangeExcelUtil.createHeadCellStyle(wb); - XSSFCellStyle contentStyle = ChangeExcelUtil.createContentCellStyle(wb); - // 行号 - int rowNum = 0; - // 创建第一页的第一行,索引从0开始 - XSSFRow row0 = sheet.createRow(rowNum++); - row0.setHeight((short) 600);// 设置行高 - sheet.setColumnWidth(1, 6000); - sheet.setColumnWidth(2, 6000); - //第二行 - XSSFRow row1 = sheet.createRow(rowNum++); - row1.setHeight((short) 500); - //第三行 - XSSFRow row2 = sheet.createRow(rowNum++); - row2.setHeight((short) 1000); - //合并单元格:excel,除了项目建筑信息的其余字段数量,项目建筑信息数据所有字段数量,一共有几组厂房,不包括重复 - ChangeExcelUtil.extracted(sheet, zdsl, sczdData, cfsl); - - // 创建第一行单元格 - for (int i = 0; i < yc.size(); i++) { - XSSFCell c00 = row0.createCell(i); - c00.setCellValue(yc.get(i)); - c00.setCellStyle(headerStyle); - } - // 创建第二行单元格 - for (int i = 0; i < ec.size(); i++) { - XSSFCell tempCell = row1.createCell(i); - tempCell.setCellValue(ec.get(i)); - tempCell.setCellStyle(headerStyle); - } - // 创建第三行单元格 - for (int i = 0; i < sc.size(); i++) { - XSSFCell tempCell = row2.createCell(i); - tempCell.setCellValue(sc.get(i)); - tempCell.setCellStyle(headerStyle); - } - //填充数据 - basicInformationService.approvalMethodfillInData(sheet, contentStyle, rowNum, info, sc, ec, sczdData / cfsl); - - // 1. 设置响应头(必须) - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - response.setCharacterEncoding("UTF-8"); - // 设置文件名(解决中文乱码) - String fileName = URLEncoder.encode("项目信息.xlsx", "UTF-8"); - response.setHeader("Content-Disposition", "attachment; filename=" + fileName); - try (ServletOutputStream out = response.getOutputStream()) { - // 3. 将 Workbook 写入响应流 - wb.write(out); - out.flush(); - } finally { - wb.close(); - } + public void exportInfo(HttpServletResponse response){ + List pE = basicInformationService.selectList(); + ExcelUtil util = new ExcelUtil<>(ProjectExcelInfo.class); + util.exportExcel(response, pE, "项目数据"); } @@ -438,53 +291,43 @@ public class BasicInformationController extends BaseController { util.exportExcel(response, filteredList, "基本信息"); } - /** - * word导出 - */ - @ApiOperation(value = "word导出") - @PostMapping(value = "/word_export") - public void word_export(HttpServletResponse response, @RequestParam List ids) throws Exception { - - //设置n值为0 用来检查是否为一个文件 - int n = 0; - for (Long id : ids) { - n++; - //b1是word里面需要的值 - BasicInformationResponse b1 = basicInformationService.selectOne(id); - Map data = new HashMap<>(); - data.put("name", b1.getBasicInformation().getName()); - data.put("ssgnq", b1.getBasicInformation().getSsgnq()); - data.put("jsdd", b1.getBasicInformation().getJsdd()); - data.put("xmfrdwxz",b1.getBasicInformation().getXmfrdwxz()); - data.put("tyshxydm",b1.getBasicInformation().getTyshxydm()); - data.put("sgdw",b1.getBasicInformation().getSgdw()); - data.put("sjdw",b1.getBasicInformation().getSjdw()); - data.put("begainTime",b1.getBasicInformation().getBegainTime()); - data.put("endTime",b1.getBasicInformation().getEndTime()); - data.put("projectLeader",b1.getBasicInformation().getProjectLeader()); - data.put("phone",b1.getBasicInformation().getPhone()); - data.put("zydmj",b1.getBasicInformation().getZydmj()); - data.put("rjl",b1.getPlanInformation().getRjl()); - data.put("zjzmj",b1.getPlanInformation().getZjzmj()); - data.put("jzds",b1.getPlanInformation().getJzds()); - data.put("bzcjzmj",b1.getPlanInformation().getBzcjzmj()); - data.put("jzmd",b1.getPlanInformation().getJzmd()); - data.put(""); - data.put(""); - data.put(""); - data.put(""); - data.put(""); - data.put(""); - - } - //如果n=1的时候就输出一个word - if (n == 1) { - - } - //如果n>1的时候输出zip - else { - - } - } +// @ApiOperation(value = "123") +//// @PreAuthorize("@ss.hasAnyRoles('admin,common')") +// @PostMapping(value = "/import1", consumes = "multipart/form-data") +// @Transactional(rollbackFor = Exception.class) +// public AjaxResult import1(@RequestPart("file") MultipartFile file) throws Exception { +// ExcelUtil util = new ExcelUtil<>(ProjectExcelInfo.class); +// List proList = util.importExcel(file.getInputStream()); +// proList.forEach(x->{ +// // 1. 分割字符串 +// String[] dates = x.getA1().split("-"); +// if (dates.length != 2) { +// throw new IllegalArgumentException("无效的日期范围格式"); +// } +// BasicInformation basicInformation = new BasicInformation(); +// basicInformation.setName(x.getName()); +// basicInformation.setXmfrdwxz(x.getXmfrdwxz()); +// basicInformation.setNature(x.getNature()); +// basicInformation.setBegainTime(dates[0].replace(".","-").trim()); +// basicInformation.setEndTime(dates[1].replace(".","-").trim()); +// basicInformation.setXzfl(x.getXzfl()); +// basicInformation.setJhtze(x.getJhtze()); +// basicInformation.setProjectLeader(x.getProjectLeader()); +// basicInformation.setPhone(x.getPhone()); +// basicInformation.setJsjd(x.getJsjd()); +// basicInformation.setJsms(x.getJsms()); +// basicInformation.setPrioritize(x.getPrioritize()); +// basicInformation.setStatus(3); +// PlanInformation planInformation = new PlanInformation(); +// planInformation.setZydmj(x.getZydmj()); +// planInformation.setRjl(x.getRjl()); +// planInformation.setZjzmj(x.getZjzmj()); +// planInformation.setBzcjzmj(x.getBzcjzmj()); +// basicInformationService.save(basicInformation); +// planInformation.setXmId(basicInformation.getId()); +// planInformationService.save(planInformation); +// }); +// return AjaxResult.success(); +// } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/gysl/controller/ZwStatsController.java b/ruoyi-admin/src/main/java/com/ruoyi/gysl/controller/ZwStatsController.java index 726ae58..6ea103f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/gysl/controller/ZwStatsController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/gysl/controller/ZwStatsController.java @@ -1,21 +1,37 @@ package com.ruoyi.gysl.controller; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.resource.ClassPathResource; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.gysl.entity.BasicInformation; +import com.ruoyi.gysl.entity.stats.AllProjectResponse; +import com.ruoyi.gysl.entity.stats.RibbonResponse; import com.ruoyi.gysl.service.BasicInformationService; import com.ruoyi.gysl.service.ZwStatsService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFRun; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.*; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * 政务统计控制层 @@ -32,6 +48,9 @@ public class ZwStatsController extends BaseController { @Resource private ZwStatsService zwStatsService; + @Value("${ruoyi.profile}") + private String fileAddress; + @Resource private BasicInformationService basicInformationService; @@ -117,5 +136,68 @@ public class ZwStatsController extends BaseController { public AjaxResult slfx() { return success(zwStatsService.slfx()); } + + + /** + * 导出项目总体报告 + */ + @ApiOperation(value = "导出项目总体报告") + @PostMapping(value = "/exportBg") + public void exportBg(HttpServletResponse response,@Valid String years) throws Exception { + + // 设置响应内容类型和头部 + response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); + response.setHeader("Content-Disposition", "attachment; filename=\"example.docx\""); + //获取总体项目情况 + AllProjectResponse allProjectResponse = zwStatsService.allProject(years); + //获取功能区 + List ribbon = zwStatsService.ribbon(years); + //获取投资主体 + List investors = zwStatsService.investors(years); + Map dt = new HashMap<>(); + dt.put("{{years}}",years); + dt.put("{{allProject}}",allProjectResponse.getAllProject()); + dt.put("{{allGrossArea}}",allProjectResponse.getAllGrossArea()); + dt.put("{{allBuilding1}}",allProjectResponse.getAllBuilding1()); + dt.put("{{allBuilding2}}",allProjectResponse.getAllBuilding2()); + dt.put("{{allBuilding3}}",allProjectResponse.getAllBuilding3()); + dt.put("{{currentYearProject}}",allProjectResponse.getCurrentYearProject()); + dt.put("{{currentYearGrossArea}}",allProjectResponse.getCurrentYearGrossArea()); + dt.put("{{currentBuilding1}}",allProjectResponse.getCurrentBuilding1()); + dt.put("{{currentBuilding2}}",allProjectResponse.getCurrentBuilding2()); + dt.put("{{currentBuilding3}}",allProjectResponse.getCurrentBuilding3()); + +// String fatherFile = fileAddress + "/out.docx"; +// FileUtil.newFile(fatherFile); + ClassPathResource classPathResource = new ClassPathResource("ztbgmb.docx"); + try ( + InputStream inputStream = classPathResource.getStream(); + // 使用 Apache POI 处理 Word 文件(需提前引入依赖) + XWPFDocument doc = new XWPFDocument(inputStream); + ) { + // 增强的占位符替换逻辑(改进部分) + for (XWPFParagraph paragraph : doc.getParagraphs()) { + List runs = paragraph.getRuns(); + if (runs == null) continue; + for (XWPFRun run : runs) { + String text = run.getText(0); + if (text == null) continue; + // 动态替换所有模板变量 + for (Map.Entry entry : dt.entrySet()) { + if (text.contains(entry.getKey())) { + text = text.replace(entry.getKey(), entry.getValue() != null ? entry.getValue().toString() : ""); + run.setText(text, 0); + } + } + } + } + // 将文档写入到响应输出流 + try (OutputStream out = response.getOutputStream()) { + doc.write(out); + } + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/gysl/entity/stats/AllProjectResponse.java b/ruoyi-admin/src/main/java/com/ruoyi/gysl/entity/stats/AllProjectResponse.java index dc725ff..a68f514 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/gysl/entity/stats/AllProjectResponse.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/gysl/entity/stats/AllProjectResponse.java @@ -37,7 +37,7 @@ public class AllProjectResponse { private BigDecimal currentYearGrossArea; @ApiModelProperty("当年_已建数量") - private Integer currentYearBuilding1; + private Integer currentBuilding1; @ApiModelProperty("当年_在建数量") private Integer currentBuilding2; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/gysl/mapper/ZwStatsMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/gysl/mapper/ZwStatsMapper.java index 64d3e39..bb9cfb3 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/gysl/mapper/ZwStatsMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/gysl/mapper/ZwStatsMapper.java @@ -48,5 +48,15 @@ public interface ZwStatsMapper { * 产业导向目录分析 */ List mlfx(); + + /** + * 产业导向细分产业分析总数 + */ + int allXfcyfx(); + + /** + * 产业导向目录分析总数 + */ + int allMlfx(); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/gysl/service/impl/ZwStatsServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/gysl/service/impl/ZwStatsServiceImpl.java index cd87f2a..e415546 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/gysl/service/impl/ZwStatsServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/gysl/service/impl/ZwStatsServiceImpl.java @@ -74,16 +74,7 @@ public class ZwStatsServiceImpl implements ZwStatsService { */ @Override public List xfcyfx() { - if (!redisCache.hasKey("xfcyfx")) { - List mlfx = zwStatsMapper.xfcyfx(); - redisCache.setCacheList("xfcyfx", mlfx); - return mlfx; - } else { - List mlfx = redisCache.getCacheList("xfcyfx"); - return mlfx.stream() - .map(obj -> (RibbonResponse) obj) - .collect(Collectors.toList()); - } + return zwStatsMapper.xfcyfx(); } /** @@ -91,16 +82,7 @@ public class ZwStatsServiceImpl implements ZwStatsService { */ @Override public List mlfx() { - if (!redisCache.hasKey("ml")) { - List mlfx = zwStatsMapper.mlfx(); - redisCache.setCacheList("ml", mlfx); - return mlfx; - } else { - List mlfx = redisCache.getCacheList("ml"); - return mlfx.stream() - .map(obj -> (RibbonResponse) obj) - .collect(Collectors.toList()); - } + return zwStatsMapper.mlfx(); } /** @@ -109,37 +91,13 @@ public class ZwStatsServiceImpl implements ZwStatsService { @Override public List slfx() { List a1 = new ArrayList<>(); - List mlfx1; - if (redisCache.hasKey("xfcyfx")) { - mlfx1 = redisCache.getCacheList("xfcyfx").stream() - .map(obj -> (RibbonResponse) obj) - .collect(Collectors.toList()); - } else { - mlfx1 = zwStatsMapper.xfcyfx(); - } - int count1 = 0; - for (RibbonResponse x : mlfx1) { - count1 += x.getCount(); - } RibbonResponse r1 = new RibbonResponse(); - r1.setCount(count1); + r1.setCount(zwStatsMapper.allXfcyfx()); r1.setSsgnq("细分产业分析"); - a1.add(r1); - List mlfx2; - if (redisCache.hasKey("ml")) { - mlfx2 = redisCache.getCacheList("ml").stream() - .map(obj -> (RibbonResponse) obj) - .collect(Collectors.toList()); - } else { - mlfx2 = zwStatsMapper.xfcyfx(); - } - int count2 = 0; - for (RibbonResponse x : mlfx2) { - count2 += x.getCount(); - } RibbonResponse r2 = new RibbonResponse(); - r2.setCount(count2); + r2.setCount(zwStatsMapper.allMlfx()); r2.setSsgnq("目录分析"); + a1.add(r1); a1.add(r2); return a1; } diff --git a/ruoyi-admin/src/main/resources/mapper/ZwStatsMapper.xml b/ruoyi-admin/src/main/resources/mapper/ZwStatsMapper.xml index 9eedd37..7c7c5e9 100644 --- a/ruoyi-admin/src/main/resources/mapper/ZwStatsMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/ZwStatsMapper.xml @@ -40,7 +40,7 @@ CASE WHEN LEFT(a.begain_time, 4) = YEAR(NOW()) and a.xzfl = 1 THEN 1 ELSE 0 END - ), 0) AS currentYearBuilding1, + ), 0) AS currentBuilding1, IFNULL(SUM( @@ -146,5 +146,21 @@ ORDER BY b.dict_value;-- 按字典排序(可选)` + + diff --git a/ruoyi-admin/src/main/resources/ztbgmb.docx b/ruoyi-admin/src/main/resources/ztbgmb.docx new file mode 100644 index 0000000..c5beacf --- /dev/null +++ b/ruoyi-admin/src/main/resources/ztbgmb.docx @@ -0,0 +1,12 @@ + 苏州工业园区工业上楼项目总体分析报告 + {{years}}年 + + 一、总体项目概况 + 苏州工业园区积极推进工业上楼模式,截至{{years}}年,园区规划工业上楼项目总数共计{{allProject}}个,总建筑面积约{{allGrossArea}}万平方米,其中已建项目{{allBuilding1}}个,在建项目{{allBuilding2}}个,拟建项目{{allBuilding3}}个,这些项目广泛分布于城市核心区域及郊区新兴产业片区,通过垂直化空间利用,提升土地利用效率,推进产业升级与集聚发展。 + 二、当年项目情况 + {{years}}年,苏州工业园区新开工上楼项目总数共计{{currentYearProject}}个,新开工项目总建筑面积达到{{currentYearGrossArea}}万平方米,已建项目{{currentBuilding1}}个,在建项目{{currentBuilding2}}个,拟建项目{{currentBuilding3}}个,力求为企业提供优质的生产和办公环境,同时在建设标准和质量上提出更高要求。 + 三、功能区情况分析 + 截至xxxx年,项目总数共xx个,其中高端制造与国际贸易区项目数量占xx个,独墅湖科教创新区项目数量占xx个,阳澄湖半岛旅游度假区项目数量占xx个,金鸡湖商务区项目数量占xx个,苏相合作区项目数量占xx个。 + 四、投资主体情况分析 + 截至xxxx年,项目总数共xx个,国企投资占xx个,民企投资占xx个,外企投资占xx个。 +