Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.35 KB | None | 0 0
  1. package com.itsallbinary.utility.pdfgraphics;
  2.  
  3. import java.io.FileWriter;
  4. import java.io.IOException;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.stream.Collectors;
  10.  
  11. /**
  12. * Create PDF file without any library from scratch.
  13. *
  14. * Include multiple pages, text and graphics
  15. *
  16. * @author itsallbinary
  17. *
  18. */
  19. public class PDFWithTextAndGraphics {
  20.  
  21. public static void main(String[] args) throws IOException {
  22.  
  23. /*
  24. * Create text stream with few lines
  25. */
  26. TextStreamObject textStreamObject = new TextStreamObject("F1", 18, 30, 100, "Hello World");
  27. textStreamObject.add("F1", 11, 30, 40, "Hope you all are enjoying Its All Binary articles!");
  28. textStreamObject.add("F1", 11, 30, 30, "Now let's create PDF with 3 pages, texts & graphics.");
  29.  
  30. /*
  31. * First page with above text stream
  32. */
  33. PageObject page1 = new PageObject();
  34. page1.addAttribute("Resources", new FontObject("F1", "Times-Roman"));
  35. page1.addContent(textStreamObject);
  36. page1.addAttribute("MediaBox", "[0 0 300 200]");
  37.  
  38. /*
  39. * Create graphic stream with few graphics.
  40. */
  41. GraphicStreamObject graphicStreamObject = new GraphicStreamObject();
  42. graphicStreamObject.addFilledRectangle(100, 600, 50, 75, "0.75 g");
  43. graphicStreamObject.addLine(100, 100, 400, 500);
  44.  
  45. /*
  46. * Second page with above graphics
  47. */
  48. PageObject page2 = new PageObject();
  49. page2.addContent(graphicStreamObject);
  50.  
  51. /*
  52. * Create curve & color graphics.
  53. */
  54. GraphicStreamObject graphicCurveStreamObject = new GraphicStreamObject();
  55. graphicCurveStreamObject.addBezierCurve(300, 300, 300, 400, 400, 400, 400, 300, "0.0 0.0 0.5", 10,
  56. "0.5 0.1 0.2");
  57.  
  58. /*
  59. * Third page with above curve & color graphics.
  60. */
  61. PageObject page3 = new PageObject();
  62. page3.addContent(graphicCurveStreamObject);
  63.  
  64. /*
  65. * Prepare pages & catalog objects.
  66. */
  67. PageCollectionObject pageCollectionObject = new PageCollectionObject();
  68. pageCollectionObject.addPages(page1, page2, page3);
  69. CatalogObject catalogObject = new CatalogObject(pageCollectionObject);
  70.  
  71. /*
  72. * Build final PDF.
  73. */
  74. PDF pdf = new PDF(catalogObject);
  75.  
  76. /*
  77. * Write PDF to a file.
  78. */
  79. FileWriter fileWriter = new FileWriter("generatedPDFWithGraphics.pdf");
  80. fileWriter.write(pdf.build());
  81. fileWriter.close();
  82.  
  83. }
  84.  
  85. }
  86.  
  87. /**
  88. * Representation of entire PDF file.
  89. *
  90. */
  91. class PDF {
  92.  
  93. private CatalogObject catalogObject;
  94.  
  95. private int objectCount = 0;
  96.  
  97. public PDF(CatalogObject catalogObject) {
  98. this.catalogObject = catalogObject;
  99. }
  100.  
  101. public String build() {
  102. populateObjectNumbers();
  103. StringBuilder pdf = new StringBuilder();
  104. pdf.append("%PDF-1.1\n\n");
  105.  
  106. pdf.append(catalogObject.build());
  107. pdf.append(catalogObject.getPages().build());
  108.  
  109. for (PageObject page : catalogObject.getPages().getPages()) {
  110. pdf.append(page.build());
  111. if (page.getContent() != null) {
  112. pdf.append(page.getContent().build());
  113. }
  114. }
  115.  
  116. pdf.append("trailer\n << /Root " + catalogObject.getReference().getObjectNumber() + " "
  117. + catalogObject.getReference().getGeneration() + " R" + "\n /Size " + (objectCount + 1) + "\n >>\n"
  118. + "%%EOF");
  119.  
  120. return pdf.toString();
  121. }
  122.  
  123. private void populateObjectNumbers() {
  124. catalogObject.setObjectNumber(++objectCount);
  125. catalogObject.getPages().setObjectNumber(++objectCount);
  126.  
  127. for (PageObject page : catalogObject.getPages().getPages()) {
  128. page.setObjectNumber(++objectCount);
  129.  
  130. if (page.getContent() != null) {
  131. page.getContent().setObjectNumber(++objectCount);
  132.  
  133. }
  134. }
  135. }
  136.  
  137. }
  138.  
  139. /**
  140. * Representation of reference to any PDF object.
  141. *
  142. */
  143. class PDFObjectReference {
  144. private int objectNumber;
  145.  
  146. private int generation = 0; // Hardcode as it remains same always
  147.  
  148. int getObjectNumber() {
  149. return objectNumber;
  150. }
  151.  
  152. int getGeneration() {
  153. return generation;
  154. }
  155.  
  156. void setObjectNumber(int objectNumber) {
  157. this.objectNumber = objectNumber;
  158. }
  159.  
  160. }
  161.  
  162. /**
  163. * Abstract Representation of PDF objects. All objects in PDF must extend this.
  164. *
  165. */
  166. abstract class PDFObject {
  167.  
  168. private PDFObjectReference reference = new PDFObjectReference();
  169.  
  170. private Map<String, Object> attributes = new HashMap<>();
  171.  
  172. public PDFObject(String type) {
  173. super();
  174. this.attributes.put("Type", type);
  175. }
  176.  
  177. public void addAttribute(String key, Object value) {
  178. this.attributes.put(key, value);
  179. }
  180.  
  181. public abstract void addSpecificAttributes();
  182.  
  183. public String build() {
  184.  
  185. addSpecificAttributes();
  186.  
  187. StringBuilder pdfObject = new StringBuilder();
  188. pdfObject.append(reference.getObjectNumber()).append(" ").append(reference.getGeneration()).append(" obj\n ")
  189. .append(buildObject()).append("\nendobj\n\n");
  190.  
  191. return pdfObject.toString();
  192. }
  193.  
  194. public StringBuilder buildObject() {
  195. StringBuilder pdfObject = new StringBuilder();
  196. pdfObject.append("<< \n");
  197.  
  198. for (String key : attributes.keySet()) {
  199.  
  200. Object value = attributes.get(key);
  201. if (value instanceof String) {
  202. pdfObject.append("\n /").append(key).append(" ").append(((String) value).contains("[") ? "" : "/")
  203. .append(value);
  204. } else if (value instanceof Integer) {
  205. pdfObject.append("\n /").append(key).append(" ").append(value);
  206. } else if (value instanceof PDFObject) {
  207. pdfObject.append("\n /").append(key).append(" \n").append(((PDFObject) value).buildObject());
  208. } else if (value instanceof PDFObjectReference[]) {
  209.  
  210. pdfObject.append("\n /").append(key).append(" [");
  211. for (PDFObjectReference ref : (PDFObjectReference[]) value) {
  212. pdfObject.append(ref.getObjectNumber() + " " + ref.getGeneration() + " R ");
  213. }
  214. pdfObject.append("]");
  215. } else if (value instanceof PDFObjectReference) {
  216. pdfObject.append("\n /").append(key).append(" ")
  217. .append(((PDFObjectReference) value).getObjectNumber() + " "
  218. + ((PDFObjectReference) value).getGeneration() + " R ");
  219. }
  220. }
  221. pdfObject.append(" >>");
  222.  
  223. return pdfObject;
  224. }
  225.  
  226. public void setObjectNumber(int objectNumber) {
  227. this.reference.setObjectNumber(objectNumber);
  228. }
  229.  
  230. PDFObjectReference getReference() {
  231. return reference;
  232. }
  233.  
  234. }
  235.  
  236. /**
  237. * Representation of catalog object
  238. *
  239. */
  240. class CatalogObject extends PDFObject {
  241.  
  242. private PageCollectionObject pages;
  243.  
  244. public CatalogObject(PageCollectionObject pageCollectionObject) {
  245. super("Catalog");
  246. this.pages = pageCollectionObject;
  247. }
  248.  
  249. @Override
  250. public void addSpecificAttributes() {
  251. addAttribute("Pages", pages.getReference());
  252. }
  253.  
  254. PageCollectionObject getPages() {
  255. return pages;
  256. }
  257.  
  258. }
  259.  
  260. /**
  261. * Representation of page object.
  262. *
  263. */
  264. class PageObject extends PDFObject {
  265.  
  266. private StreamObject content;
  267.  
  268. public PageObject() {
  269. super("Page");
  270. }
  271.  
  272. public void addContent(StreamObject streamObject) {
  273. content = streamObject;
  274. }
  275.  
  276. @Override
  277. public void addSpecificAttributes() {
  278. addAttribute("Contents", content.getReference());
  279. }
  280.  
  281. StreamObject getContent() {
  282. return content;
  283. }
  284.  
  285. }
  286.  
  287. /**
  288. * Representation of pages object
  289. *
  290. */
  291. class PageCollectionObject extends PDFObject {
  292.  
  293. private List<PageObject> pages = new ArrayList<>();
  294.  
  295. public PageCollectionObject() {
  296. super("Pages");
  297. }
  298.  
  299. public void addPages(PageObject... pageObjects) {
  300. for (PageObject pageObject : pageObjects) {
  301. addPage(pageObject);
  302. }
  303. }
  304.  
  305. public void addPage(PageObject pageObject) {
  306. this.pages.add(pageObject);
  307. pageObject.addAttribute("Parent", getReference());
  308. }
  309.  
  310. @Override
  311. public void addSpecificAttributes() {
  312. addAttribute("Count", Integer.valueOf(pages.size()));
  313. PDFObjectReference[] refArr = new PDFObjectReference[pages.size()];
  314. for (int i = 0; i < pages.size(); i++) {
  315. refArr[i] = pages.get(i).getReference();
  316. }
  317. addAttribute("Kids", refArr);
  318. }
  319.  
  320. List<PageObject> getPages() {
  321. return pages;
  322. }
  323.  
  324. }
  325.  
  326. /**
  327. * Representation of font object
  328. *
  329. */
  330. class FontObject extends PDFObject {
  331.  
  332. public FontObject(String fontAliasName, String fontName) {
  333. super(null);
  334.  
  335. PDFObject fontDef = new PDFObject("Font") {
  336. @Override
  337. public void addSpecificAttributes() {
  338. addAttribute("Subtype", "Type1");
  339. addAttribute("BaseFont", fontName);
  340. }
  341. };
  342. fontDef.addSpecificAttributes();
  343.  
  344. PDFObject fontAlias = new PDFObject(null) {
  345. @Override
  346. public void addSpecificAttributes() {
  347. addAttribute(fontAliasName, fontDef);
  348. }
  349. };
  350. fontAlias.addSpecificAttributes();
  351.  
  352. addAttribute("Font", fontAlias);
  353. }
  354.  
  355. @Override
  356. public void addSpecificAttributes() {
  357.  
  358. }
  359.  
  360. }
  361.  
  362. /**
  363. * Abstract Representation of stream object
  364. *
  365. */
  366. abstract class StreamObject extends PDFObject {
  367.  
  368. public StreamObject() {
  369. super(null);
  370. }
  371.  
  372. public abstract String buildStream();
  373.  
  374. public void addSpecificAttributes() {
  375. addAttribute("Length", Integer.valueOf(100));
  376. }
  377.  
  378. @Override
  379. public StringBuilder buildObject() {
  380. StringBuilder sb = super.buildObject();
  381. sb.append("\nstream").append(buildStream()).append("\nendstream");
  382. return sb;
  383. }
  384.  
  385. }
  386.  
  387. /**
  388. * Representation of text stream object
  389. *
  390. */
  391. class TextStreamObject extends StreamObject {
  392.  
  393. private static final String BEGIN_TEXT = "BT";
  394. private static final String END_TEXT = "ET";
  395. private static final String TEXT_FONT = "Tf";
  396. private static final String TEXT_OFFSET = "Td";
  397. private static final String SHOW_TEXT = "Tj";
  398.  
  399. private List<String> texts = new ArrayList<>();
  400.  
  401. public TextStreamObject(String fontAlias, int fontSize, int xPos, int yPos, String text) {
  402. add(fontAlias, fontSize, xPos, yPos, text);
  403.  
  404. }
  405.  
  406. public void add(String fontAlias, int fontSize, int xPos, int yPos, String text) {
  407. this.texts.add(" \n " + BEGIN_TEXT + " \n /" + fontAlias + " " + fontSize + " " + TEXT_FONT + " \n " + xPos
  408. + " " + yPos + " " + TEXT_OFFSET + "\n (" + text + ") " + SHOW_TEXT + "\n" + END_TEXT + "\n");
  409. }
  410.  
  411. @Override
  412. public String buildStream() {
  413. return texts.stream().collect(Collectors.joining());
  414. }
  415. }
  416.  
  417. /**
  418. * Representation of graphics stream object
  419. *
  420. */
  421. class GraphicStreamObject extends StreamObject {
  422.  
  423. private static final String MOVE_POINTER = "m";
  424. private static final String LINE = "l";
  425. private static final String LINE_WIDTH = "w";
  426. private static final String RECTANGLE = "re";
  427. private static final String FILL = "f";
  428. private static final String BEZIER_CURVE = "c";
  429. private static final String BORDER_COLOR = "rg";
  430. private static final String FILL_COLOR = "RG";
  431. private static final String STROKE = "S";
  432. private static final String CLOSE_FILL_STROKE = "b";
  433.  
  434. private List<String> graphics = new ArrayList<>();
  435.  
  436. public void addLine(int xFrom, int yFrom, int xTo, int yTo) {
  437. this.graphics.add(
  438. "\n " + xFrom + " " + yFrom + " " + MOVE_POINTER + " " + xTo + " " + yTo + " " + LINE + " " + STROKE);
  439. }
  440.  
  441. public void addRectangle(int a, int b, int c, int d) {
  442. this.graphics.add("\n " + a + " " + b + " " + c + " " + d + " " + RECTANGLE + " " + STROKE);
  443. }
  444.  
  445. public void addFilledRectangle(int a, int b, int c, int d, String color) {
  446. this.graphics.add("\n" + color);
  447. this.graphics.add("\n " + a + " " + b + " " + c + " " + d + " " + RECTANGLE + " " + FILL + " " + STROKE);
  448. }
  449.  
  450. public void addBezierCurve(int movex, int movey, int a, int b, int c, int d, int e, int f, String borderColor,
  451. int borderWidth, String fillColor) {
  452. this.graphics.add("\n" + borderWidth + " " + LINE_WIDTH);
  453. this.graphics.add("\n" + fillColor + " " + FILL_COLOR);
  454. this.graphics.add("\n" + borderColor + " " + BORDER_COLOR);
  455. this.graphics.add("\n" + movex + " " + movey + " " + MOVE_POINTER);
  456. this.graphics.add("\n " + a + " " + b + " " + c + " " + d + " " + e + " " + f + " " + BEZIER_CURVE + " \n "
  457. + CLOSE_FILL_STROKE);
  458. }
  459.  
  460. @Override
  461. public String buildStream() {
  462. return graphics.stream().collect(Collectors.joining());
  463. }
  464.  
  465. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement