Java中字符串根据宽度(像素)换行的问题

目录
  • Java 字符串根据宽度(像素)换行
    • 根据像素宽度进行换行
  • Java字符串根据宽度(像素)进行换行及Pdf合并
    • 1、工具类最终版前奏
    • 2、工具类最终版
    • 3、项目中具体使用
      • 3.1 controller层
      • 3.2 serviceImpl层
    • 4、工具类补充

Java 字符串根据宽度(像素)换行

在一些场景下,我们经常会通过判断字符串的长度,比如个数来实现换行,但是中文、英文、数字、其实在展示的时候同样长度的字符串,其实它的宽度是不一样的,这也是们我通俗意义上说的宽度(像素)

根据像素宽度进行换行

需求:

/**
     * 10、自己做图片 ,根据文本宽度进行换行
     */
    @Test
    public void creatMyImage(){
        //整体图合成
        BufferedImage bufferedImage = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
        //设置图片的背景色
        Graphics2D main = bufferedImage.createGraphics();
        main.fillRect(0, 0, 500, 500);
        String text = "111122223所以比传统纸巾更环保3334441比传统纸巾更环11111111111111122223所以比传统纸巾更环保3334441比传统纸巾更环11111111111111122223所以比传统纸巾更环保3334441比传统纸巾更环11111111111111122223所以比传统纸巾更环保3334441比传统纸巾更环11111111111";
        Graphics2D textG = bufferedImage.createGraphics() ;
        textG.setColor(new Color(37,37,37));
        Font hualaoContentFont = new Font("PingFang SC", Font.PLAIN, 20);
        textG.setFont(hualaoContentFont);
        textG.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        drawString(textG,text,30,100,4,10,50,true,false);
        //存储到本地
        String saveFilePath = "/Users/healerjean/Desktop/new.png";
        saveImageToLocalDir(bufferedImage, saveFilePath);
    }
    /**
     *
     * @param g
     * @param text 文本
     * @param lineHeight 行高(注意字体大小的控制哦)
     * @param maxWidth 行宽
     * @param maxLine 最大行数
     * @param left 左边距 //整段文字的左边距
     * @param top 上边距 //整顿文字的上边距
     * @param trim 是否修剪文本(1、去除首尾空格,2、将多个换行符替换为一个)
     * @param lineIndent 是否首行缩进
     */
    public static void drawString(Graphics2D g, String text, float lineHeight, float maxWidth, int maxLine, float left,
                                  float top, boolean trim, boolean lineIndent) {
        if (text == null || text.length() == 0) return;
        if(trim) {
            text = text.replaceAll("\\n+", "\n").trim();
        }
        if(lineIndent) {
            text = "  " + text.replaceAll("\\n", "\n  ");
        }
        drawString(g, text, lineHeight, maxWidth, maxLine, left, top);
    }
    /**
     *
     * @param g
     * @param text 文本
     * @param lineHeight 行高
     * @param maxWidth 行宽
     * @param maxLine 最大行数
     * @param left 左边距
     * @param top 上边距
     */
    private static void drawString(Graphics2D g, String text, float lineHeight, float maxWidth, int maxLine, float left,
                                   float top) {
        if (text == null || text.length() == 0) return;
        FontMetrics fm = g.getFontMetrics();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            sb.append(c);
            int stringWidth = fm.stringWidth(sb.toString());
            if (c == '\n' || stringWidth > maxWidth) {
                if(c == '\n') {
                    i += 1;
                }
                if (maxLine > 1) {
                    g.drawString(text.substring(0, i), left, top);
                    drawString(g, text.substring(i), lineHeight, maxWidth, maxLine - 1, left, top + lineHeight);
                } else {
                    g.drawString(text.substring(0, i - 1) + "…", left, top);
                }
                return;
            }
        }
        g.drawString(text, left, top);
    }

Java字符串根据宽度(像素)进行换行及Pdf合并

实际开发中,我们经常会通过判断字符串的长度,比如个数来实现换行,但是中文、英文、数字在展示的时候同样长度的字符串,其实它的宽度是不一样的,这也是们我通俗意义上说的宽度(像素)。

下面结合jasper套打打印业务来说明。

1、工具类最终版前奏

package main;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
public class SubstringStr {

	/**
	 * 1、自己做图片,根据文本宽度进行换行
	 */
	public void creatMyImage(String text) {
		// 整体图合成
		BufferedImage bufferedImage = new BufferedImage(595, 842, BufferedImage.TYPE_INT_RGB);
		// 设置图片的背景色
		Graphics2D main = bufferedImage.createGraphics();
		main.fillRect(0, 0, 1500, 2600);

		Graphics2D graphics2d = bufferedImage.createGraphics();
		graphics2d.setColor(new Color(37, 37, 37));
		Font hualaoContentFont = new Font("宋体", Font.PLAIN, 20);
		graphics2d.setFont(hualaoContentFont);
		graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);

		drawString1(graphics2d, text, 30, 500, 28, 71, 20, false, false, 0);

		// 存储到本地
		String saveFilePath = "D:\\new.png";
		saveImageToLocalDir(bufferedImage, saveFilePath);
	}

	private void saveImageToLocalDir(BufferedImage img, String saveFilePath) {
		try {
			//bufferedimage 转换成 inputstream
			ByteArrayOutputStream bs = new ByteArrayOutputStream();
			ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
			ImageIO.write(img, "jpg", imOut);
			InputStream inputStream = new ByteArrayInputStream(bs.toByteArray());
			long length = imOut.length();
			OutputStream outStream = new FileOutputStream(saveFilePath);

			//输出流
		    byte[] bytes = new byte[1024];
		    long count = 0;
		    while(count < length){
		        int len = inputStream.read(bytes, 0, 1024);
		        count +=len;
		        outStream.write(bytes, 0, len);
		    }
		    outStream.flush();
			inputStream.close();
			outStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param graphics2d
	 * @param text  文本
	 * @param lineHeight 行高(注意字体大小的控制哦)
	 * @param maxWidth 行宽
	 * @param maxLine  最大行数
	 * @param left 左边距 //整段文字的左边距
	 * @param top 上边距 //整段文字的上边距
	 * @param trim  是否修剪文本(1、去除首尾空格,2、将多个换行符替换为一个)
	 * @param lineIndent 是否首行缩进
	 */
	public static void drawString1(Graphics2D graphics2d, String text, float lineHeight, float maxWidth, int maxLine, float left,
			float top, boolean trim, boolean lineIndent, int resultLine) {
		if (text == null || text.length() == 0)
			return;
		if (trim) {
			text = text.replaceAll("\\n+", "\n").trim();
			System.err.println("执行了。。。。");
		}
		if (lineIndent) {
			text = "  " + text.replaceAll("\\n", "\n  ");
			System.err.println("执行了=====");
		}
		drawString2(graphics2d, text, lineHeight, maxWidth, maxLine, left, top, resultLine);
	}
	/**
	 *
	 * @param graphics2d
	 * @param text 文本
	 * @param lineHeight 行高
	 * @param maxWidth 行宽
	 * @param maxLine 最大行数
	 * @param left 左边距
	 * @param top 上边距
	 */
	private static void drawString2(Graphics2D graphics2d, String text, float lineHeight, float maxWidth, int maxLine,
			float left, float top, int resultLine) {

		if (text == null || text.length() == 0) {
			return;
		}

		FontMetrics fm = graphics2d.getFontMetrics();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < text.length(); i++) {
			char strChar = text.charAt(i);
			sb.append(strChar);

			int stringWidth = fm.stringWidth(sb.toString());
			if (strChar == '\n' || stringWidth > maxWidth) {
				if (strChar == '\n') {
					i += 1;
					System.out.println("\n字符串内容为:" + text.substring(0, i));
				}
				if (maxLine > 1) {
					resultLine = resultLine + 1;
					System.err.println("\nif中字符串内容为:" + text.substring(0, i));
					graphics2d.drawString(text.substring(0, i), left, top);

					drawString2(graphics2d, text.substring(i), lineHeight, maxWidth, maxLine - 1, left, top + lineHeight, resultLine);

				} else {
					System.err.println("\nelse中字符串内容为:" + text.substring(0, i));
					graphics2d.drawString(text.substring(0, i - 1) + "…", left, top);
				}
				return;
			}
		}
		System.err.println("最后字符串内容为:" + text + "===行数为:" + resultLine);
		graphics2d.drawString(text, left, top);
	}

	public static void main(String[] args) {
		String text = "111122223所以比传统纸巾更环保3334441比传统纸巾更环11111111111111122223所以比传统纸巾更环保3334441比传统纸巾"
				+ System.getProperty("line.separator") + "更环66666666"+ System.getProperty("line.separator")
				+ "所以比传统纸巾更环保3334441比传统纸巾更环。。。。。。。"
				+ "111111122223所以比传统纸巾更环保3334441比传统纸巾更环11111111111";
		SubstringStr test = new SubstringStr();
		test.creatMyImage(text);
		System.out.println("输入图片完成:D:/new.png");
	}
}

2、工具类最终版

package com.sinosoft.emr.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SubstrUtil {
	private static int index = 0;

	/**
	 * 1、自己做图片 ,根据文本宽度进行换行
	 */
	public static Map<String, Object> creatMyImage(String text, Font font, int appointRow, Map<String, Object> map, int rows) {
		index = 0;
		// 整体图合成
		BufferedImage bufferedImage = new BufferedImage(595, 842, BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics2d = bufferedImage.createGraphics();
		graphics2d.setColor(new Color(37, 37, 37));

		graphics2d.setFont(font);
		graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
		map = myDrawString(graphics2d, text, 30, 500, appointRow, 71, 20, map, rows);
		return map;
	}	

	/**
	 * 2、根据宽度截取字符串
	 * @param graphics2d
	 * @param text 文本
	 * @param lineHeight 行高
	 * @param maxWidth 行宽
	 * @param maxLine 最大行数
	 * @param left 左边距
	 * @param top 上边距
	 */
	private static Map<String, Object> myDrawString(Graphics2D graphics2d, String text, int lineHeight, int maxWidth,
			int maxLine, int left, int top, Map<String, Object> map, int rows) {
		if (text == null || text.length() == 0) {
			return map;
		}

		FontMetrics fm = graphics2d.getFontMetrics();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < text.length(); i++) {
			char strChar = text.charAt(i);
			sb.append(strChar);
			int stringWidth = fm.stringWidth(sb.toString());
			int strLength = text.substring(0, i).length();

			if (strLength >= 53 || strChar == '\n' || stringWidth >= maxWidth) {
				if (strChar == '\n') {
					i += 1;
//					System.out.println("字符串内容为:" + text.substring(0, i));
				}
				if (maxLine > 1) {
					rows = rows + 1;
//					System.err.println("if中字符串内容为:" + text.substring(0, i));
					char value = ' ', value1 = ' ';
					try {
						value = text.substring(i).charAt(0);
						value1 = text.substring(i - 1).charAt(0);
					} catch (Exception e) {
						/*e.printStackTrace();*/
						System.err.println("----" + e.getMessage());
					}

					if (isChinesePunctuation(value) && checkCharCN(value1)) {
						map.put("row" + rows, text.substring(0, i - 1));
						myDrawString(graphics2d, text.substring(i - 1), lineHeight, maxWidth, maxLine - 1, left, top + lineHeight, map, rows);
					} else {
						map.put("row" + rows, text.substring(0, i));
						myDrawString(graphics2d, text.substring(i), lineHeight, maxWidth, maxLine - 1, left, top + lineHeight, map, rows);
					}

					index = index + i;
					map.put("index", index);
//					System.err.println("---下标" + index);
				} else {
					rows = rows + 1;
					map.put("row" + rows, text.substring(0, i));
//					System.err.println("else中字符串内容为:" + text.substring(0, i));

					index = index + i;
					map.put("index", index);
				}
				return map;
			}
		}
		return map;
	}

	// 2.1 判断字符是否是中文
	public static boolean checkCharCN(char c) {
		String s = String.valueOf(c);
		String regex = "[\u4e00-\u9fa5]";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(s);
		return m.matches();
	}

	// 2.2 判断字符是否是中文标点符号
	public static boolean isChinesePunctuation(char c) {
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);

		if (ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
				|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
				|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS
				|| ub == Character.UnicodeBlock.VERTICAL_FORMS) {
			return true;

		} else {
			return false;
		}
	}	

	/**
	 * 3、针对jasper中宽度较短的文本
	 * @author wanglong
	 * @date   2020年11月10日下午7:12:14
	 */
	public static Map<String, Object> creatShortImage(String text, Font font, int appointRow, Map<String, Object> map, int rows) {
		index = 0;
		// 整体图合成
		BufferedImage bufferedImage = new BufferedImage(595, 842, BufferedImage.TYPE_INT_RGB);
		// 设置图片的背景色
		Graphics2D main = bufferedImage.createGraphics();
		main.fillRect(0, 0, 595, 842);

		Graphics2D graphics2d = bufferedImage.createGraphics();
		graphics2d.setColor(new Color(37, 37, 37));

		graphics2d.setFont(font);
		graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
		map = myDrawShortString(graphics2d, text, 30, 230, appointRow, 71, 20, map, rows);
		return map;
	}
	// 3.1
	private static Map<String, Object> myDrawShortString(Graphics2D graphics2d, String text, int lineHeight, int maxWidth,
			int maxLine, int left, int top, Map<String, Object> map, int rows) {
		if (text == null || text.length() == 0) {
			return map;
		}

		FontMetrics fm = graphics2d.getFontMetrics();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < text.length(); i++) {
			char strChar = text.charAt(i);
			sb.append(strChar);

			int stringWidth = fm.stringWidth(sb.toString());
			if (strChar == '\n' || stringWidth > maxWidth) {
				if (strChar == '\n') {
					i += 1;
					//System.out.println("字符串内容为:" + text.substring(0, i));
				}
				if (maxLine > 1) {
					rows = rows + 1;
					//System.err.println("if中字符串内容为:" + text.substring(0, i));
					map.put("row" + rows, text.substring(0, i));
					map.put("row_len" + rows, stringWidth);

					myDrawShortString(graphics2d, text.substring(i), lineHeight, maxWidth, maxLine - 1, left, top + lineHeight, map, rows);

				} else {
					rows = rows + 1;
					map.put("row" + rows, text.substring(0, i));
					map.put("row_len" + rows, stringWidth);
					//System.err.println("else中字符串内容为:" + text.substring(0, i));
				}

				return map;
			}
		}
		return map;
	} 

	public static void main(String[] args) {
		Map<String, Object> map = new LinkedHashMap<>();
		int rows = 0;
		int appointRow = 4;
		Font font = new Font("宋体", Font.PLAIN, 12);
		String text = "111122223所以比传统纸巾更环保3334441比传统纸巾更环11111111111111122223所以比传统纸巾更环保3334441测试数据"
				+ System.getProperty("line.separator") + "在仿苹果官网垃圾桶时, 设计出的UI使用PingFang SC 字体"+ System.getProperty("line.separator")
				+ "天津市防控指挥部消息称,经排查,滨海新区中新天津纸巾更环保3334441比传统纸巾更环666所以比传统纸巾更环保3334441比传统纸巾更环8888";

		int length = text.length();
		map = creatMyImage(text, font, appointRow, map, rows);
		if (length > index) {
			System.out.println("还剩余文本:" + text.substring(index));
		}
		System.out.println("\n<<--->>>rows=" + rows + ", map="+map);
	}
}

说明:此工具类我们经理进行了改造,生成的文本内容符合中国人的书写习惯:行首不能是标点符号。如果行首是标点符号,上一行的最后一个文字会挪至本行。

3、项目中具体使用

3.1 controller层

/**
 * 4、打印 病程记录
 * @author wanglong
 * @date 2020年3月4日 下午5:22:57
 */
@RequestMapping(value = "printEmrCourse", method = RequestMethod.GET, produces = MediaType.APPLICATION_PDF_VALUE)
public void printEmrCourse(@RequestParam(value = "id", required = true) String id,
		@RequestParam(value = "courseType", required = true) String courseType,
		@RequestParam(value = "token", required = true) String token, HttpServletResponse response) {
	List<String> filePathList = new ArrayList<String>();

	Map<String, Map<String, Object>> map = iEmrCourseSelectBusi.selectEmrCourseData(id, courseType, token);
	try {
		if (map.size() > 0) {
			for (int i = 0, len = map.size(); i < len; i++) {
				if (i % 2 == 0) {
					String path1 = iEmrCourseSelectBusi.getCoursePdf(map.get("map" + i), "emrCourseLeft.jasper");
					if (!"".equals(path1)) {
						filePathList.add(path1);
					}
				} else {
					String path2 = iEmrCourseSelectBusi.getCoursePdf(map.get("map" + i), "emrCourseRight.jasper");
					if (!"".equals(path2)) {
						filePathList.add(path2);
					}
				}
			}

			iEmrCourseSelectBusi.printEmrCoursePdf(filePathList, response);
		}

	} catch (Exception e) {
		e.printStackTrace();
	}
}

3.2 serviceImpl层

@Service("iEmrCourseSelectBusi")
public class EmrCourseBusiSelectImpl extends EmrCourseSelectServiceImpl implements IEmrCourseSelectBusi{
	private static final long serialVersionUID = 1L;
	private Font font = new Font("宋体", Font.PLAIN, 12);
	// 读取配置文件里的jasper路径
    @Value("${jasperPath}")
    private String jasperPath;

    /**
     * 4、打印 病程记录
     * @author wanglong
     * @date   2020年11月9日下午3:49:23
     */
    @Override
    public Map<String, Map<String, Object>> selectEmrCourseData(String id, String courseType, String token) {
	    Map<String, Map<String, Object>> resultMap = new LinkedHashMap<>();
	    Map<String, Object> map = new LinkedHashMap<>();
	    int rows = 0, appointRow = 28;

	    StringBuffer bufferStr = new StringBuffer();
	    String lineBreak = System.getProperty("line.separator"); // 换行符

	    try {
		    EmrCourse record = emrCourseMapper.selectByPrimaryKey(id);
		    if (record != null) {
			    map.put("patientName", record.getPatientName());
			    map.put("fkHosRegisterHosNo", record.getFkHosRegisterHosNo());

			    String recordTime = DateUtil.dateToString(record.getCourseRecordTime(), "yyyy-MM-dd HH:mm");
			    String doctorName = record.getDoctorRealName();

			    if ("1".equals(courseType)) {
				    bufferStr.append(recordTime + lineBreak);

				    String tempStr = record.getGeneralRecords() == null ? "" : record.getGeneralRecords();
				    String blankStr = "";
				    if (!"".equals(tempStr)) {
					    blankStr = StringDealUtil.getSubString(blankStr, tempStr);
				    }

				    String generalRecords = record.getGeneralRecords() == null ? "" : (blankStr + lineBreak);
				    bufferStr.append(generalRecords);
			    } 

			    String updateName = record.getUpdateOprName();
			    String opraterName = updateName == null ? record.getAddOprName() : updateName;
			    bufferStr.append("\t\t\t\t\t\t\t\t\t签   名:" + opraterName + lineBreak);

			    String text = bufferStr.toString();
			    int length = text.length();

			    map = SubstrUtil.creatMyImage(text, font, appointRow, map, rows);
			    map.put("pageNum", "1");
			    resultMap.put("map0", map);

			    int index = (int) map.get("index");
			    if (length > index) {
				    String _text = StringDealUtil.getSurplusText(text, index);
				    resultMap = this.getOtherMap(_text, appointRow, resultMap, 1);
			    }
		    }
	    } catch (Exception e) {
		e.printStackTrace();
	    }

	    return resultMap;
    }

    // 4.1 截取文本获取其余map
    private Map<String, Map<String, Object>> getOtherMap(String text, int appointRow,
		    Map<String, Map<String, Object>> resultMap, int i) {
	    int length = text.length();

	    Map<String, Object> map = new LinkedHashMap<>();
	    map = SubstrUtil.creatMyImage(text, font, appointRow, map, 0);
	    map.put("pageNum", i + 1 + "");

	    resultMap.put("map"+ i, map);

	    int index = (int) map.get("index");
	    if (length > index) {
		    String _text = StringDealUtil.getSurplusText(text, index);
		    resultMap = this.getOtherMap(_text, appointRow, resultMap, i+1);
	    }

	    return resultMap;
    } 

    /**
     * 5、生成pdf
     * @author wanglong
     * @date   2020年11月9日下午1:52:42
     */
    @Override
    public String getCoursePdf(Map<String, Object> map, String jasperName) {
	    String fileInfo = "";
	    Instant timestamp = Instant.now();
	    try {
		    JRDataSource jrDataSource = new JRBeanCollectionDataSource(null);

		    File reportFile = new File(jasperPath + jasperName);
	        String exportFileName = timestamp.toEpochMilli() + ".pdf";
	        fileInfo = jasperPath + exportFileName;

	        //调用工具类
	        JasperHelper.exportPdf2File(jasperPath + exportFileName, reportFile, map, jrDataSource);

	    } catch (Exception e) {
		    e.printStackTrace();
	    }

	    return fileInfo;
    }

    /**
     * 5.1  合成pdf进行打印
     * @author wanglong
     * @date   2020年11月9日下午1:52:58
     */
    @Override
    public void printEmrCoursePdf(List<String> filePathList, HttpServletResponse response) {
	    List<File> files = new ArrayList<File>();
	    try {
	    	if (filePathList != null && filePathList.size() > 0) {
		    	for (int i = 0, length = filePathList.size(); i < length; i++) {
		    		String pathName = filePathList.get(i);
		    		files.add(new File(pathName));
		    	}

		    	String newFileName = Instant.now().toEpochMilli() + "病程记录mul2one.pdf";
			    String targetPath = jasperPath + newFileName;
		    	File newFile = PdfMergeUtil.mulFile2One(files, targetPath);

			    if (newFile.exists()) {
			    	// 先将单个的pdf文件删除
			    	for (File file : files) {
			    		if (file.exists() && file.isFile()) {
			    			file.delete();
			    		}
			    	}
			    	newFile.getName();
			    	PdfUtil.downloadFile(response, targetPath, newFileName);
			    }
		    }

	    } catch (Exception e) {
		e.printStackTrace();
	    }
    }
}

4、工具类补充

package utils;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.util.JRLoader;
import java.io.*;
import java.util.Map;
public class JasperHelper {
	/**
	 * 1、直接导出pdf文件
	 * @author wanglong
	 * @date   2020年10月31日下午9:10:41
	 */
	public static void exportPdf2File(String defaultFilename, File is, Map<String, Object> parameters, JRDataSource conn) {
		try {
			JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);
			JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, conn);

			exportPdfToFile(jasperPrint, defaultFilename);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 1.1 导出Pdf
	private static void exportPdfToFile(JasperPrint jasperPrint, String defaultFilename) throws IOException, JRException {
		FileOutputStream ouputStream = new FileOutputStream(new File(defaultFilename));
		JasperExportManager.exportReportToPdfStream(jasperPrint, ouputStream);

		ouputStream.flush();
		ouputStream.close();
	}
}
package utils;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
/**
 * @name: PdfMergeUtil
 * @Description: pdf合并拼接工具类
 * @author wanglong
 * @date   2020年2月25日下午4:33:13
 * @version 1.0
 */
public class PdfMergeUtil {
	/**
     * @Description: pdf合并拼接
     * @param files 文件列表
     * @param targetPath 合并到
     * @throws IOException
     */
    public static File mulFile2One(List<File> files,String targetPath) throws IOException{
        // pdf合并工具类
        PDFMergerUtility mergePdf = new PDFMergerUtility();
        for (File f : files) {
            if(f.exists() && f.isFile()){
                // 循环添加要合并的pdf
                mergePdf.addSource(f);
            }
        }
        // 设置合并生成pdf文件名称
        mergePdf.setDestinationFileName(targetPath);
        // 合并pdf
        mergePdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());

        return new File(targetPath);
    }
}
package utils;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * 导出PDF
 */
public class PdfUtil {
    // 下载
    public static void downloadFile(HttpServletResponse response, String filePath, String fileName) {
		if (fileName != null) {
			response.reset();
			response.setContentType("application/pdf");

			// 设置文件路径
			File file = new File(filePath);
			if (file.exists()) {
				byte[] buffer = new byte[1024];
				FileInputStream fis = null;
				BufferedInputStream bis = null;
				try {
					fis = new FileInputStream(file);
					bis = new BufferedInputStream(fis);
					OutputStream os = response.getOutputStream();
					int i = bis.read(buffer);
					while (i != -1) {
						os.write(buffer, 0, i);
						i = bis.read(buffer);
					}
					System.out.println("download success!");

				} catch (Exception e) {
					e.printStackTrace();

				} finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                file.delete();
            }
        }
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java Scanner类用法及nextLine()产生的换行符问题实例分析

    本文实例讲述了Java Scanner类用法及nextLine()产生的换行符问题.分享给大家供大家参考,具体如下: 分析理解:Scanner sc = new Scanner(System.in); package cn.itcast_01; /* * Scanner:用于接收键盘录入数据. * * 前面的时候: * A:导包 * B:创建对象 * C:调用方法 * * 分析理解:Scanner sc = new Scanner(System.in); * System类下有一个静态的字段:

  • Java 替换字符串中的回车换行符的方法

    使用正则表达式进行替换: 代码片段: String documentTxt = EntityUtils.toString(entity,"gbk");//获取数据 documentTxt=documentTxt.replaceAll("[\\t\\n\\r]", "");//将内容区域的回车换行去除 说明:String类的replaceAll就有正则替换功能. \t为制表符 \n为换行 \r为回车 java正则使用: 示例方法: 复制代码 代码如

  • Java读取String分行字符串的方法

    1.场景:String字符串中带有分行,需要提取每一行出来处理. 2.参考代码如下: public static void main(String[] args) throws IOException{ String s="1\r\n2\r\n3\r\n \r\nabd\r\n"; BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(s.getBytes(Charse

  • Java中String类(字符串操作)的10个常见问题和解决方法

    本文介绍Java中关于String最常见的10个问题: 1. 字符串比较,使用 "==" 还是 equals() ?简单来说, "==" 判断两个引用的是不是同一个内存地址(同一个物理对象).而 equals 判断两个字符串的值是否相等.除非你想判断两个string引用是否同一个对象,否则应该总是使用 equals()方法.如果你了解 字符串的驻留 ( String Interning ) 则会更好地理解这个问题 2. 对于敏感信息,为何使用char[]要比Stri

  • Java中字符串根据宽度(像素)换行的问题

    目录 Java 字符串根据宽度(像素)换行 根据像素宽度进行换行 Java字符串根据宽度(像素)进行换行及Pdf合并 1.工具类最终版前奏 2.工具类最终版 3.项目中具体使用 3.1 controller层 3.2 serviceImpl层 4.工具类补充 Java 字符串根据宽度(像素)换行 在一些场景下,我们经常会通过判断字符串的长度,比如个数来实现换行,但是中文.英文.数字.其实在展示的时候同样长度的字符串,其实它的宽度是不一样的,这也是们我通俗意义上说的宽度(像素) 根据像素宽度进行换

  • 基于Java中字符串内存位置详解

    前言 之前写过一篇关于JVM内存区域划分的文章,但是昨天接到蚂蚁金服的面试,问到JVM相关的内容,解释一下JVM的内存区域划分,这部分答得还不错,但是后来又问了Java里面String存放的位置,之前只记得String是一个不变的量,应该是要存放在常量池里面的,但是后来问到new一个String出来应该是放到哪里的,这个应该是放到堆里面的,后来又问到String的引用是放在什么地方的,当时傻逼的说也是放在堆里面的,现在总结一下:基本类型的变量数据和对象的引用都是放在栈里面的,对象本身放在堆里面,

  • java中字符串转整数及MyAtoi方法的实现

    java中字符串转整数及MyAtoi方法的实现 该题虽然和我们正常使用的字符串转整数的API中函数不一致,但是通过增加了很多额外的边界或者异常处理,可以锻炼算法思维的敏锐性和处理边界异常等问题的能力. 思路:字符串题一般考查的都是边界条件.特殊情况的处理.所以遇到此题一定要问清楚各种条件下的输入输出应该是什么样的. 这里已知的特殊情况有: 能够排除首部的空格,从第一个非空字符开始计算 允许数字以正负号(+-)开头 遇到非法字符便停止转换,返回当前已经转换的值,如果开头就是非法字符则返回0 在转换

  • Java中字符串的一些常见方法分享

    1.Java中字符串的一些常见方法 复制代码 代码如下: /** *  */package com.you.model; /** * @author Administrator * @date 2014-02-24 */public class Replace { /**  * @param args  */ public static void main(String[] args)  {  /**   * 原字符串   */  String str = "78454545855ksdjnf

  • 浅谈java中字符串数组、字符串、整形之间的转换

    字符串数组转字符串(只能通过for循环): String[] str = {"abc", "bcd", "def"}; StringBuffer sB = new StringBuffer(); for (int i = 0; i < str.length;i++) { sB.append(str[i]); } String s = sB.toString(); 字符数组转字符串可以通过下面的方式: char[] data = {"

  • 基于Java中字符串indexof() 的使用方法

    Java中字符串中子串的查找共有四种方法(indexof()) indexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置.如果没有找到子字符串,则返回-1. 如果 startindex 是负数,则 startindex 被当作零.如果它比最大的字符位置索引还大,则它被当作最大的可能索引. Java中字符串中子串的查找共有四种方法,如下: 1.int indexOf(String str) :返回第一次出现的指定子字符串在此字符串中的索引. 2.int indexOf(St

  • Java中字符串中连续相同字符去重方法

    最近参加了一个面试,问到了如何在一个字符串中连续相同字符去重,想了想用正则表达式应该可以轻松实现.可是由于长时间没有编码了,而且由于原先的工作用到的比较少.具体的自己就不会写正则表达式用到的类名什么的了.总之就是面试没有过了. 回来再网上搜了搜,本来以为可以很容易找到相应的内容,可是找了半天没有找到我想要的结果.后来在某个相似问题求助中看到了相应答案,不过还是有所区别,根据该问题的解决思路,最后实现了. 代码如下: public class Test { public static void m

  • 一文解开java中字符串编码的小秘密(干货)

    简介 在本文中你将了解到Unicode和UTF-8,UTF-16,UTF-32的关系,同时你还会了解变种UTF-8,并且探讨一下UTF-8和变种UTF-8在java中的应用. 一起来看看吧. Unicode的发展史 在很久很久以前,西方世界出现了一种叫做计算机的高科技产品. 初代计算机只能做些简单的算数运算,还要使用人工打孔的程序才能运行,不过随着时间的推移,计算机的体积越来越小,计算能力越来越强,打孔已经不存在了,变成了人工编写的计算机语言. 一切都在变化,唯有一件事情没有变化.这件事件就是计

  • 详细图解Java中字符串的初始化

    目录 前言 常量池 反编译代码验证字符串初始化操作 总结 前言 在深入学习字符串类之前,我们先搞懂JVM是怎样处理新生字符串的.当你知道字符串的初始化细节后,再去写String s = "hello"或String s = new String("hello")等代码时,就能做到心中有数. 首先得搞懂字符串常量池的概念,下面进入正文吧. 常量池 把经常用到的数据存放在某块内存中,避免频繁的数据创建与销毁,实现数据共享,提高系统性能. 八种基础数据类型除了float和

  • 一文详解Java中字符串的基本操作

    目录 一.遍历字符串案例 二.统计字符次数案例 三.字符串拼接案例 四.字符串反转案例 五.帮助文档查看String常用方法 一.遍历字符串案例 需求:键盘录入一个字符串,使用程序实现在控制台遍历该字符串 思路: 1.键盘录入一个字符串,用 Scanner 实现 2.遍历字符串,首先要能够获取到字符串中的每一个字符 public char charAt(int index):返回指定索引处的char值,字符串的索引也是从0开始的 3.遍历字符串,其次要能够获取到字符串的长度 public int

随机推荐