private void addSumBottom() {
    for (int i = 0; i < book.getNumberOfSheets(); i++) {
      Sheet sheet = book.getSheetAt(i);

      Row row = sheet.createRow(sheet.getLastRowNum() + 1);
      row.setHeight((short) (ROW_HEIGHT + 100));

      for (int j = 0; j < 1000000; j++) {
        if (StringUtils.isBlank(CellUtils.getStringValue(sheet.getRow(0).getCell(j)))
            && StringUtils.isBlank(CellUtils.getStringValue(sheet.getRow(2).getCell(j)))) {
          break;
        }
        Cell cell = row.createCell(j);
        cell.setCellStyle(Style.get(book).SUM);
        if (j == 0) {
          cell.setCellValue("合计");
        } else {
          cell.setCellValue(0);
        }

        if (j >= 7) {
          cell.setCellType(Cell.CELL_TYPE_FORMULA);
          cell.setCellFormula(
              String.format(
                  "SUM(%s%s:%s%s)",
                  CellUtils.convertToABC(j + 1),
                  5,
                  CellUtils.convertToABC(j + 1),
                  sheet.getLastRowNum()));
        }
      }
      sheet.addMergedRegion(
          new CellRangeAddress(sheet.getLastRowNum(), sheet.getLastRowNum(), 0, 6));
    }

    for (int i = 0; i < book.getNumberOfSheets(); i++) {
      Sheet sheet = book.getSheetAt(i);
      for (int j = 4; j <= sheet.getLastRowNum(); j++) {
        Row row = sheet.getRow(j);
        for (int k = 0; k <= row.getLastCellNum(); k++) {
          Cell cell = row.getCell(k);
          if (cell == null) {
            continue;
          }

          if ("数量".equals(CellUtils.getStringValue(sheet.getRow(2).getCell(k)))) {
            cell.setCellStyle(Style.get(book).SUM);
          }
        }
      }
    }
  }
 /**
  * Adds RoundhouseAction to the build actions. This is applicable for each build.
  *
  * @param build the build
  * @param launcher the launcher
  * @param listener the listener
  * @return true
  * @throws InterruptedException when there's an interruption
  * @throws IOException when there's an IO error
  */
 @Override
 public final boolean perform(
     final AbstractBuild<?, ?> build, final Launcher launcher, final BuildListener listener)
     throws InterruptedException, IOException {
   Style style = Style.get(build.getResult());
   String fact = factGenerator.random();
   build.getActions().add(new RoundhouseAction(style, fact));
   return true;
 }
 /**
  * Gets the RoundhouseAction as the project action. This is applicable for each job and only when
  * there's at least one build in the job.
  *
  * @param project the project
  * @return the project action
  */
 @Override
 public final Action getProjectAction(final AbstractProject<?, ?> project) {
   Action action = null;
   if (project.getLastBuild() != null) {
     Style style = Style.get(project.getLastBuild().getResult());
     String fact = factGenerator.random();
     action = new RoundhouseAction(style, fact);
   }
   return action;
 }