I’m participating in nuggets Creators Camp # 4, click here to learn more and learn together!

preface

In the previous article, hutool was introduced to send emails, but in the actual business is not called its sendMail method can achieve business, sometimes we have to transform it or write their own method implementation, so today let’s see how I realize the function of sending emails and multiple attachments.

One. Implementation ideas

Dynamic Excel is generated dynamically because Excel table data required by business may increase or decrease fields according to later needs, so it cannot be fixed. It can be queried through SQL and then create dynamic table headers and corresponding data columns according to fields. Secondly, it is necessary to send multiple attachments when sending an email. If it is not good to send the generated Excel file in the way of data flow, this point is also feasible. Let’s see the specific implementation.

Two. Concrete implementation

1. Generate dynamic Excel

1) Dynamic header generation

/*** * dynamically create table headers *@param map 
 * @return* /
public static String[] createTitle(Map<String, Object> map) {
    int count = 0;
    String strings[] = new String[map.size()];
    for( Map.Entry<String, Object> entry : map.entrySet() ) {
        strings[count] = entry.getKey();
        count++;
    }
    return strings;
}
Copy the code

2) Draw Excel, including table headers and some simple processing of quantity types

  /** * Create Excel *@paramSheetName Sheet name *@paramThe title title *@paramValues content *@paramWb HSSFWorkbook object *@return* /
    public static HSSFWorkbook createHSSFWorkbook(String sheetName, String[] title, String[][] values, HSSFWorkbook wb) {
        // Create an HSSFWorkbook that corresponds to an Excel file
        if (wb == null) {
            wb = new HSSFWorkbook();
        }
        // Add a sheet to workbook, which corresponds to the sheet in Excel file
        HSSFSheet sheet = wb.createSheet(sheetName);
        // Add row 0 in sheet. Note that old poI limits the number of rows in Excel
        HSSFRow row = sheet.createRow(0);
        // Create the cell and set the value header to center
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER); // Create a centered format
        // Declare column objects
        HSSFCell cell = null;
        // Create a title
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
            cell.setCellStyle(style);
        }
        HSSFCellStyle contextstyle =wb.createCellStyle();
        // Create content
        for (int i = 0; i < values.length; i++) {
            row = sheet.createRow(i + 1);
            for (int j = 0; j < values[i].length; j++) {
                Boolean isNum = false;
                Boolean isInteger=false;// Whether data is an integer
                HSSFCell contentCell = row.createCell(j);
              // Assign the contents to the corresponding column objects in order
                if (null! =values[i][j] ||"".equals(values[i][j])) {
                    // Check whether data is numeric
                    isNum = values[i][j].toString().matches("^ (-? \d+)(\.\d+)? $");
                    // Check whether data is an integer (whether the decimal part is 0)
                    isInteger=values[i][j].toString().matches("^ [\ +]? [\d]*$");
                }
                // Set the data format here
                if (isNum) {
                    HSSFDataFormat df = wb.createDataFormat(); 
                    if (isInteger) {
                    // The data format displays only integers
                     contextstyle.setDataFormat(df.getBuiltinFormat("# 0 #,"));
                    }else{/ keep a decimal point contextstyle. SetDataFormat (df) getBuiltinFormat ("#, # # 0.0"));/
                    }
                    // Set the cell format
                    contentCell.setCellStyle(contextstyle);
                    // Set the cell content to type double
                    contentCell.setCellValue(Double.parseDouble(values[i][j]));
                } else {
                    contentCell.setCellStyle(contextstyle);
                    // Set the cell content to character typecontentCell.setCellValue(values[i][j]); }}// Set the automatic column width
            sheet.autoSizeColumn(i);
            sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 17 / 10);
        }
        return wb;
    }
Copy the code

List<LinkedHashMap<String, Object>> = List<LinkedHashMap >> = List<LinkedHashMap<String, Object>> = List<LinkedHashMap >> = List<LinkedHashMap >> = List< String, Object>> = List<LinkedHashMap > = List< String, Object>> So use LinkedHashMap to receive it and make it smooth

2. Send emails

1) Send multiple people and multiple attachments

/ * * *@paramSubject Mail title *@paramMapList attachment information is available for multiple attachments *@paramContent Email content *@paramReceiveList Recipient collection */
public static void sendEmail(String subject, List<Map<String,Object>> mapList, String content, List<String> receiveList, String smtpHost, String userName, String password) {
    logger.info("send report start>>>>>>>>>>>>");
    Session session = EmailUtils.getSession(smtpHost, userName, password);
    MimeMessage message = new MimeMessage(session);
    InternetAddress[] toArray = new InternetAddress[receiveList.size()];
    try {
        // Receive list
        for (int i = 0; i < toArray.length; i++) {
            toArray[i] = new InternetAddress(receiveList.get(i));
        }
        message.setSubject(subject);
        message.setSentDate(new Date());
        message.setFrom(new InternetAddress(userName));
        message.addRecipients(MimeMessage.RecipientType.TO, toArray);
        // Create the message section
        BodyPart messageBodyPart = new MimeBodyPart();
        / / message
        messageBodyPart.setContent(content, "text/html; charset=utf-8");
        // Create multiple messages and send multiple attachments
        Multipart multipart = new MimeMultipart();
        // Sets the text message section
        multipart.addBodyPart(messageBodyPart);
        // Add attachments here to stream directly
        for (Map<String, Object> map : mapList) {
            messageBodyPart = new MimeBodyPart();
            DataSource source = new ByteArrayDataSource((byte[])map.get("os"), "application/excel");
            messageBodyPart.setDataHandler(new DataHandler(source));
            // Avoid Chinese garbled characters
            messageBodyPart.setFileName(MimeUtility.encodeText(map.get("title") + ".xlsx"));
            multipart.addBodyPart(messageBodyPart);
        }
        // Send the full message
        message.setContent(multipart);
        // Send a message
        Transport.send(message);
        logger.info("send email successful>>>>>>>>>>>>");
    } catch (Exception e) {
        e.printStackTrace();
        logger.error("send email error",e.getMessage()); }}Copy the code

2) Send the result and data, @1 is the screenshot of the target email received, @2 is the test data, @2 is the arrow marked in the SQL field, directly query the Chinese and create the table header through createTitle, and generate the corresponding column according to its length

@ 1

@ 22) About recipient configuration

Here the recipient can be configured to the database or Redis, need to add or delete changes immediately effective, because it is not commonly used, there is no need to put in the configuration file.

Common errors and solutions

1. The SMTP function is enabled, but an @1 error message is reported after a period of time. Generate the authorization code @2 and replace the password. The following example is Sina email.

@ 1

@ 2

summary

Many estimates when get demand began to write code, actually such written code quality is not high, to demand should draw a draft or a figure should be how to deal with, and how to deal with, even though the code is changed, the efficiency of the latter must be much higher, and the development of the time can write flexible method is flexible, Don’t just focus on the current business implementation. In addition, due to the limitation of space, part of the code can only be shown in the way of screenshots.