# xml 和 json 的处理

# 要求

​- 读入以下的 score.xml 文件,并转化为 JSON Object 对象,输出 JSON Object 的字符串表达式。最后,根据 JSON Object 的值和 score.xml 的样式,重新生成 score2.xml。

<student>
<name>Tom</name>
<subject>math</subject>
<score>80</score>
</student>
  • 读取和写入 xml 方法不限,JSON 处理方法不限。

# maven 依赖

<dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.6.1</version>
</dependency>
<!--net.sf.json-lib 可能不需要 -->
<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier>
</dependency>
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20160810</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>

# 本体

import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.json.JSONObject;
import org.json.XML;
import org.dom4j.io.OutputFormat;
import java.io.*;
public class Xml2Json {
    public static void xml2Json() throws Exception {
        InputStream in = new FileInputStream("src/main/resources/score.xml");
        String xml = IOUtils.toString(in);
        JSONObject xmlJSONObj = XML.toJSONObject(xml);
        String json = xmlJSONObj.toString();
        writeFile(json, "src/main/resources/score.json");
        System.out.println(json);
    }
    public static void json2Xml() throws Exception {
        InputStream in = new FileInputStream("src/main/resources/score.json");
        String json = IOUtils.toString(in);
        JSONObject jsonObject = new JSONObject(json);
        String xml = XML.toString(jsonObject);
        xml = format(xml);
        writeFile(xml, "src/main/resources/score2.xml");
    }
    public static void writeFile(String s, String url) {
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(url)))) {
            bw.write(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static String format(String str) throws Exception {
        Document doc = new SAXReader().read(new StringReader(str));
        OutputFormat formater = OutputFormat.createPrettyPrint();
        formater.setEncoding("UTF-8");
        StringWriter out = new StringWriter();
        XMLWriter writer = new XMLWriter(out, formater);
        writer.write(doc);
        writer.close();
        return out.toString();
    }
    public static void main(String[] args) throws Exception {
        xml2Json();
        json2Xml();
    }
}

# xls、doc、pdf 的处理和条形码的生成

# 要求

  • 读取 student.xslx 里面的数据,根据预设的 student.docx 模板,生成学生具体的信息文档,最后转化为 pdf 文档。
  • 整个程序可以分成多个步骤,或者整合为一个程序。

# maven 依赖

<dependency>
    <groupId>com.lowagie</groupId>
    <artifactId>itext</artifactId>
    <version>2.1.7</version>
</dependency>
<dependency>
    <groupId>fr.opensagres.xdocreport</groupId>
    <artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
    <version>1.0.6</version>
</dependency>
<!--org.apache.pdfbox 可能不需要 -->
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.13</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>xmpbox</artifactId>
    <version>2.0.13</version>
</dependency>
<!--com.itextpdf 可能不需要 -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.15</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.15</version>
</dependency>
<dependency>
    <groupId>org.apache.xmlbeans</groupId>
    <artifactId>xmlbeans</artifactId>
    <version>3.1.0</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.15</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.15</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.3</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.3.3</version>
</dependency>

# 本体

import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.lowagie.text.Font;
import com.lowagie.text.pdf.BaseFont;
import fr.opensagres.xdocreport.itext.extension.font.IFontProvider;
import fr.opensagres.xdocreport.itext.extension.font.ITextFontRegistry;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.List;
public class Main {
    public static final int CODEWIDTH = 130;
    public static int HEIGHT = 80;
    public static final int CODEHEIGHT = 70;
    public static int FONTSIZE = 10;
    public static void main(String[] args) throws Exception {
        // 读取 xls, 存入 List 中
        List<String> list = readXls();
        // 生成条形码
        File file = new File("src/main/resources/code.png");
        generateCode(file, list.get(2), CODEWIDTH, CODEHEIGHT);
        generateFont(file, list.get(2));
        // 构造替换映射
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("{name}", list.get(0));
        params.put("{sex}", list.get(1));
        params.put("{barcode}", list.get(2));
        // 解析 doc 并替换
        parserDoc(params);
        //doc 转换为 pdf
        writePdf();
        System.out.println("generate successfully!");
    }
    public static List<String> readXls() throws Exception {
        List<String> list = new ArrayList<>();
        InputStream ExcelFileToRead = new FileInputStream("src/main/resources/student.xlsx");
        XSSFWorkbook workbook = new XSSFWorkbook(ExcelFileToRead);
        XSSFSheet sheet = workbook.getSheetAt(0);
        // 先按行读取,再在每行中按列读取
        Iterator rows = sheet.iterator();
        while (rows.hasNext()) {
            XSSFRow row = (XSSFRow) rows.next();
            Iterator cells = row.cellIterator();
            while (cells.hasNext()) {
                XSSFCell cell = (XSSFCell) cells.next();
                // 判断是否为字符串还是数字
                if (cell.getCellTypeEnum() == CellType.STRING) {
                    list.add(cell.getStringCellValue());
                } else if (cell.getCellTypeEnum() == CellType.NUMERIC) {
                    list.add("" + cell.getNumericCellValue());
                }
            }
        }
        ExcelFileToRead.close();
        return list;
    }
    public static void replaceRun(XWPFParagraph xwpfParagraph, Map<String, Object> params) throws Exception {
        // 获得 XWPFRuns
        List<XWPFRun> runs = xwpfParagraph.getRuns();
        if (runs.size() > 0) {
            for (XWPFRun re : runs) {
                // 判断是否为非空 run
                if (re.text() != null || re.text().length() > 0) {
                    String match = re.text();
                    // 判断是否能被替换
                    if (params.containsKey(match)) {
                        // 判断是否是条形码
                        if (match.equals("{barcode}")) {
                            xwpfParagraph.removeRun(0);
                            XWPFRun run = xwpfParagraph.createRun();
                            int format = XWPFDocument.PICTURE_TYPE_PNG;
                            // 添加条形码图片
                            run.addPicture(new FileInputStream("src/main/resources/code_new.png"), format,
                                    "src/main/resources/code_new.png", Units.toEMU(CODEWIDTH), Units.toEMU(CODEHEIGHT));
                        } else {
                            // 正常文本替换
                            xwpfParagraph.removeRun(0);
                            XWPFRun run = xwpfParagraph.createRun();
                            run.setText(params.get(match).toString());
                        }
                    }
                }
            }
        }
    }
    public static void parserDoc(Map<String, Object> params) throws Exception {
        InputStream WordFileToRead = new FileInputStream("src/main/resources/student.docx");
        XWPFDocument xwpfDocument = new XWPFDocument(WordFileToRead);
        // 获得 IBodyElement
        List<IBodyElement> iBodyElements = xwpfDocument.getBodyElements();
        for (IBodyElement ibs : iBodyElements) {
            BodyElementType bodyElementType = ibs.getElementType();
            // 是否为表格
            if (bodyElementType == BodyElementType.TABLE) {
                XWPFTable xwpfTable = (XWPFTable) ibs;
                // 获得行
                List<XWPFTableRow> rows = xwpfTable.getRows();
                for (XWPFTableRow row : rows) {
                    // 获得单元格
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        List<XWPFParagraph> paras = cell.getParagraphs();
                        for (XWPFParagraph para : paras) {
                            // 替换 Run
                            replaceRun(para, params);
                        }
                    }
                }
            } else if (bodyElementType == BodyElementType.PARAGRAPH) {
                XWPFParagraph xwpfParagraph = (XWPFParagraph) ibs;
                // 替换 Run
                replaceRun(xwpfParagraph, params);
            }
        }
        OutputStream outputStream = new FileOutputStream("src/main/resources/student_new.docx");
        xwpfDocument.write(outputStream);
        WordFileToRead.close();
        outputStream.close();
    }
    public static void writePdf() throws Exception {
        FileInputStream inputStream = new FileInputStream("src/main/resources/student_new.docx");
        XWPFDocument document = new XWPFDocument(inputStream);
        PdfOptions options = PdfOptions.create();
        options.fontProvider(new IFontProvider() {
            @Override
            public Font getFont(String familyName, String encoding, float size, int style, Color color) {
                try {
                    BaseFont bfChinese=BaseFont.createFont("C:/Windows/Fonts/simfang.ttf",BaseFont.IDENTITY_H,BaseFont.EMBEDDED);
                    Font fontChinese = new Font(bfChinese, size, style, color);
                    if (familyName != null)
                        fontChinese.setFamily(familyName);
                    return fontChinese;
                } catch(Exception e) {
                    e.printStackTrace();
                    return ITextFontRegistry.getRegistry().getFont(familyName, encoding, size, style, color);
                }
            }
        });
        PdfConverter.getInstance().convert(document, new FileOutputStream("src/main/resources/student.pdf"), options);
        inputStream.close();
    }
    public static void generateCode(File file, String code, int width, int height) {
        BitMatrix matrix = null;
        try {
            MultiFormatWriter writer = new MultiFormatWriter();
            matrix = writer.encode(code, BarcodeFormat.CODE_128, width, height, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try (FileOutputStream outputStream = new FileOutputStream(file)) {
            ImageIO.write(MatrixToImageWriter.toBufferedImage(matrix), "png", outputStream);
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void generateFont(File file, String s) throws Exception {
        BufferedImage code = ImageIO.read(file);
        BufferedImage font = new BufferedImage(CODEWIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D) font.getGraphics();
        g.clearRect(0, 0, CODEWIDTH, HEIGHT);
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, CODEWIDTH, HEIGHT);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        for (int i = 0; i < s.length(); i++) {
            g.setColor(Color.black);
            java.awt.Font font_ = new java.awt.Font("Consolas", 0, FONTSIZE);
            g.setFont(font_);
            g.drawString(s.charAt(i) + "", (FONTSIZE * 4 + CODEWIDTH - s.length() * FONTSIZE) / 2 + (i - 1) * FONTSIZE * 5 / 6, HEIGHT);
        }
        g.drawImage(code, 0, 0, null);
        g.dispose();
        File outputfile = new File("src/main/resources/code_new.png");
        ImageIO.write(font, "png", outputfile);
    }
}