คำนำ (เบื้องหลังการแนะนำ):
Apache Poi เป็นโครงการโอเพ่นซอร์สถัดไปของ Apache Foundation ซึ่งใช้ในการประมวลผลเอกสารในซีรี่ส์ Office และสามารถสร้างและแยกวิเคราะห์เอกสารในรูปแบบ Word, Excel และ PPT
มีสองเทคโนโลยีสำหรับการประมวลผลเอกสาร Word คือ HWPF (.DOC) และ XWPF (.DOCX) หากคุณคุ้นเคยกับเทคโนโลยีทั้งสองนี้คุณควรเข้าใจความเจ็บปวดจากการใช้ Java เพื่อแยกวิเคราะห์เอกสารคำ
สองปัญหาที่ใหญ่ที่สุดคือ:
อย่างแรกคือคลาสทั้งสองนี้ไม่มีคลาสแม่และอินเทอร์เฟซแบบครบวงจร (XSSF และ HSSF ประตูถัดไปทำให้ดวงตาที่ดูถูกเหยียดหยาม) ดังนั้นพวกเขาจึงไม่สามารถทำการเขียนโปรแกรมอินเทอร์เฟซในรูปแบบเดียวกัน
ประการที่สองคือไม่มีอินเทอร์เฟซสำหรับตำแหน่งสัมพัทธ์ของรูปภาพในเอกสารใน API อย่างเป็นทางการซึ่งนำไปสู่ความจริงที่ว่าแม้ว่าคุณจะได้รับรูปภาพทั้งหมดในเอกสารคุณไม่สามารถรู้ได้ว่ารูปภาพเหล่านี้อยู่ที่ไหน ในอนาคตคุณจะไม่สามารถแทรกรูปภาพในตำแหน่งที่ถูกต้อง
สำหรับจุดแรกฉันไม่มีทางเลือกนอกจากต้องศึกษาเทคโนโลยีที่เกี่ยวข้องอื่น ๆ เช่น Jacob, Doc4j ฯลฯ เพื่อดูว่ามีวิธีแก้ปัญหาอื่น ๆ หรือไม่ แต่ DOC4J ดูเหมือนจะสามารถประมวลผลเอกสาร 2007 (.docx)
สำหรับประเด็นที่สองบทความนี้จะให้ทางออกของผู้เขียน อันที่จริงนี่เป็นจุดประสงค์ของการเขียนบทความนี้ด้วย
หมายเหตุ: เพียงดูบทที่ 2 และบทที่ 3 หากคุณเพียงแค่ขอความเร็ว
1. ความรู้การเตรียมการ
1. เอกสารคำสองรูปแบบสอดคล้องกับวิธีการจัดเก็บข้อมูลที่แตกต่างกันสองวิธี
อย่างที่เราทราบกันดีว่าเอกสาร Word มีรูปแบบการจัดเก็บสองแบบ: Doc และ Docx
DOC: โดยทั่วไปเรียกว่า Word2003 ซึ่งใช้ข้อมูล การจัดเก็บไบนารี นี่ไม่ใช่จุดสนใจของการสนทนาของเราในวันนี้
DOCX: Word2007 ใช้ XML เพื่อจัดเก็บข้อมูลและรูปแบบ
บางทีคุณอาจถามว่าทำไมรูปแบบ XML ที่เห็นได้ชัดว่าเป็นเอกสารที่ลงท้ายด้วย DOCX?
มันง่ายมาก: คุณสามารถเลือกไฟล์ docx คลิกขวาเพื่อเปิดด้วยเครื่องมือการบีบอัดและคุณสามารถรับโครงสร้างไดเรกทอรีเช่นนี้:
ดังนั้นคุณคิดว่า Docx เป็นเอกสารที่สมบูรณ์ แต่ในความเป็นจริงมันเป็นเพียงไฟล์ที่บีบอัด (docx:? _?)
2. รูปแบบคำจำกัดความของ XML ในเอกสาร Word:
จากตัวอย่างก่อนหน้านี้เราได้เรียนรู้ว่าเอกสาร DOCX ใช้ไฟล์ที่ถูกบีบอัดนั่นคือ XML เพื่ออธิบายข้อมูล ดังนั้นข้อมูลในเอกสารคำที่กำหนดโดยเฉพาะอย่างไร
เนื่องจากพื้นที่เอกสารที่บีบอัดทั้งหมดจะไม่ถูกอธิบายในรายละเอียดที่นี่ ฉันจะแนะนำสองไฟล์/โฟลเดอร์สั้น ๆ :
ขั้นแรกไฟล์ document.xml ในไดเรกทอรีคำซึ่งเป็นคำจำกัดความของเนื้อหาเอกสารทั้งหมด
ประการที่สองคือโฟลเดอร์สื่อในไดเรกทอรีคำ คุณสามารถเดาเนื้อหามัลติมีเดียในเอกสารได้โดยดูที่ชื่อ:
รูปที่ 3: word/document.xml (กำหนดเนื้อหาเอกสาร)
รูปที่ 4: เนื้อหาภายใต้โฟลเดอร์ Word/Media
ต่อไปนี้เป็นเนื้อหาคีย์บางส่วนของ Document.xml เอกสาร:
A: เอกสารนิยามโครงสร้างโดยรวม:
<W: เอกสาร MC: เพิกเฉย = "W14 W15 WP14" XMLNS: M = "http://schemas.openxmlformats.org/officedocument/2006/math" xmlns: mc = "http://schemas.openxmlformatsi xmlns: o = "urn: schemas-microsoft-com: Office: Office" xmlns: r = "http://schemas.openxmlformats.org/officedocument/2006/relationships xmlns: w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns: w10 = "urn: schemas-microsoft-com: Office: Word" xmlns: w14 = "httpm: httpm: httpmmmmm xmlns: w15 = "http://schemas.microsoft.com/office/word/2012/wordml" xmlns: wne = "http://schemas.microsoft.com/office/word/2006/wordml" xmlns: wp = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns: wp14 = "http://schemas.microsoft.com/office/2010/2010/2010/2010/2010/2010/2010 xmlns: wpg = "http://schemas.microsoft.com/office/word/2010/wordprocessingcanvas" xmlns: wpg = "http://schemas.microsoft.com/office/word/2010/2010 xmlns: wpi = "http://schemas.microsoft.com/office/word/2010/wordprocessingink" xmlns: wps = "http://schemas.microsoft.com/office/word/2010/wordwordprocessingshape" xmlns: wpscustomdata = "http://www.wps.cn/officedocument/2013/wpscustomdata"> <w: body> <w: p> <w: ppr> <w: pstyle w: val = "2"> <w: keeplines w: val = "0"> </w: keeplines> <w: widowcontrol> </w: widowcontrol> <w: suppresslinenumbers w: val = "0"> </w: suppresslinenumbers> <w: pbdr> </w: top> <w: ซ้าย w: color = "auto" w: space = "0" w: val = "none"> </w: ด้านล่าง> <w: ขวา w: color = "auto" w: space = "0" w: sz = "0" w: val = "none"> </w: ขวา> </w: pbdr>
B: เนื้อหาย่อหน้าเอกสาร:
<w: p> <w: ppr> <w: pstyle w: val = "2"> </w: pstyle> <w: keepnext w: val = "0"> </w: keepnext> <w: keeplines w: val = "0"> </w: suppresslinenumbers> <w: pbdr> <w: top w: color = "auto" w: space = "0" w: sz = "0"> </w: top> <w: ซ้าย w: color = "auto" w: space = "0" w: sz = "0" w: val = "ไม่มี"> </w: ด้านล่าง> <w: ขวา w: color = "auto" w: space = "0" w: sz = "0" w: val = "ไม่มี"> </w: ขวา> </w: pbdr> W: AfterAutospacing = "0" W: ก่อน = "150" W: beforeAutOspacing = "0" W: line = "378" W: linerule = "atleast"> </w: ระยะห่าง> <w: ind w: firstline = "0" w: left = "0" w: cs = "verdana" w: hansi = "verdana" w: hint = "ค่าเริ่มต้น"> </w: rfonts> <w: iw: val = "0"> </w: i> <w: caps w: val = "0"> </w: caps> </w: ระยะห่าง> <w: sz w: val = "21"> </w: sz> <w: szcs w: val = "21"> </w: szcs> </w: rpr> </w: ppr> <w: rpr> <w: rpr> <w: rpr> w: hansi = "verdana" w: hint = "ค่าเริ่มต้น"> </w: rfonts> <w: iw: val = "0"> </w: i> <w: caps w: val = "0"> </w: caps> <w: color w: val = "404040"> w: val = "21"> </w: sz> <w: szcs w: val = "21"> </w: szcs> <w: bdr w: color = "auto" w: space = "0" w: sz = "0" w: val = "none"> </w: bdr> </w: rpr> <w: t> ผู้แต่ง: Brian Dear </w: t> </w: r> </w: p>
C: คำจำกัดความเนื้อหาภาพ:
<w: r> <w: rpr> <w: rfonts w: ascii = "verdana" w: cs = "verdana" w: hansi = "verdana" w: คำใบ้ = "ค่าเริ่มต้น"> </w: rfonts> <w: iw: val = "0"> w: val = "404040"> </w: color> <w: การเว้นวรรค w: val = "0"> </w: ระยะห่าง> <w: sz w: val = "21"> </w: sz> <w: szcs w: val = "21"> w: val = "ไม่มี"> </w: bdr> <w: shd w: fill = "fafafa" w: val = "clear"> </w: shd> </w: rpr> <w: drawing> <wp: inline distb = "0" distl = "114300" dist = "114300" cy = "5543550"> </wp: extent> <wp: effectExtent B = "0" l = "0" r = "0" t = "0"> </wp: EffectExtent> <WP: DOCPR DESCR = "IMG_256" ID = "1" NAME = "รูปภาพ 1" <A: graphicframelocks nochangeaspect = "1" xmlns: a = "http://schemas.openxmlformats.org/drawingml/2006/main"> </a: graphicframelocks> </wp: cnvgramframepr xmlns: a = "http://schemas.openxmlformats.org/drawingml/2006/main"> <a: graphicData uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns: pic = "http://schemas.openxmlformats.org/drawingml/2006/picture"> <pic: nvpicpr> <pic: cnvpr descr = "img_256" id = "1" ชื่อ = "รูปภาพ 1"> </pic nochAneAspect = "1"> </a: piclocks> </pic: cnvpicpr> </pic: nvpicpr> <pic: blipfill> <a: blip r: embed = "rid4"> </a: blip> <a: ยืด> <A: ปิด x = "0" y = "0"> </a: ปิด> <a: ext cx = "5543550" Cy = "5543550"> </a: ext> </a: xfrm> <a: prstgeom prst = "rect"> <a: ln w = "9525"> <a: nofill> </a: nofill> </a: ln> </pic: sppr> </pic: pic> </a: graphicData> </a: กราฟิก> </wp: inline> </w: การวาด> </w: r>
หากคุณสนใจคุณสามารถดูรหัส XML สามรหัสข้างต้น ฉันจะให้ข้อสรุปโดยตรงที่นี่:
เอกสาร Word Shema ไฟล์: xmlns: w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
เอกสารรูทโหนด: <w: เอกสาร> กำหนดจุดเริ่มต้นของเอกสารทั้งหมด
<W: Body> เป็นโหนดลูกของเอกสารและเนื้อหาหลักของเอกสาร
<w: p> โหนดเด็กร่างกายย่อหน้าเป็นย่อหน้าในเอกสารคำว่า
<w: r> โหนดเด็กขององค์ประกอบ p การเรียกใช้กำหนดย่อหน้าที่มีรูปแบบเดียวกันในย่อหน้า
<w: t> โหนดลูกของโหนดองค์ประกอบการเรียกใช้เป็นเนื้อหาของเอกสาร
<W: การวาดภาพ> โหนดเด็กขององค์ประกอบการเรียกใช้กำหนดรูปภาพ:
<W: อินไลน์> การวาดโหนดเด็กไม่มีการวิจัยเชิงลึกในแอปพลิเคชันเฉพาะ
<A: กราฟิก> กำหนดเนื้อหาภาพ
<Pic: Blipfill> นี่คือโหนดลูกของเอกสารกราฟิกซึ่งกำหนดดัชนีของเนื้อหาภาพ โดยเฉพาะ POI สามารถรับทรัพยากรที่เกี่ยวข้องของภาพตามชื่อนี้และคีย์เพื่อรับตำแหน่งของภาพเอกสารอยู่ที่นี่
โดยรวมแล้วเอกสารการแยกวิเคราะห์ XWPF คือการแยกวิเคราะห์เอกสาร XML บันทึกโหนดทั้งหมดแล้วแปลงเป็นคุณสมบัติที่มีประโยชน์มากขึ้นโดยให้ API สำหรับผู้ใช้
ดังนั้นเราสามารถใช้อินเทอร์เฟซที่เรามอบให้โดย POI เพื่อรับเนื้อหาเอกสารแยกวิเคราะห์ข้อมูลในเอกสารด้วยตัวคุณเองและรับย่อหน้าที่รูปภาพอยู่แน่นอนคุณสามารถทราบได้ว่าองค์ประกอบใดที่อยู่ด้านหลัง
2. การรับรู้
แพ็คเกจ com.szdfhx.reportstatistic.util; นำเข้า com.microsoft.schemas.vml.ctshape; นำเข้า org.apache.poi.xwpf.usermodel.xwpfparagraph; นำเข้า org.apache.poi.xwpf.usermodel.xwpfrun; นำเข้า org.apache.xmlbeans.xmlcursor; นำเข้า org.apache.xmlbeans.xmlobject; นำเข้า org.openxmlformats.schemas.drawingml.x2006. org.openxmlformats.schemas.drawingml.x2006.picture.ctpicture; นำเข้า org.openxmlformats.schemas.drawingml.x2006.main.ctdrawing; นำเข้า org.openxmlformats.schemas. org.openxmlformats.schemas.wordprocessingml.x2006.main.ctr; นำเข้า java.util.arraylist; นำเข้า java.util.list; นำเข้า java.util.list; นำเข้า java.util.map ReadImageInParagraph (ย่อหน้า XWPFARAGRAPH) {// รายการดัชนีภาพ <String> ImageBundLiList = arrayList ใหม่ <String> (); // รายการ XWPFRUN ทั้งหมด <XWPFRUN> ในวรรค RunList = PARAGRAPH.GETRUNS (); สำหรับ (xwpfrun run: runlist) {// xwpfrun เป็นแอตทริบิวต์ของตัวเองที่สร้างขึ้นโดย POI หลังจากแยกวิเคราะห์องค์ประกอบ XML ไม่สามารถแยกวิเคราะห์ได้ผ่าน XML มันจะต้องถูกแปลงเป็น Ctr Ctr Ctr = run.getCtr (); // การทำธุรกรรมขององค์ประกอบเด็ก xmlcursor c = ctr.newcursor (); // นี่คือการได้รับองค์ประกอบของเด็กทั้งหมด: C.SelectPath ("./*"); ในขณะที่ (C.TonextSelection ()) {XMLObject O = C.GetObject (); // ถ้าองค์ประกอบลูกอยู่ในรูปแบบของ <w: การวาด> ให้ใช้ ctdrawing เพื่อบันทึกภาพถ้า (o อินสแตนซ์ของ ctdrawing) {ctdrawing drawing = (ctdrawing) o; ctinline [] ctinlines = drawing.getInlinearray (); สำหรับ (ctinline ctinline: ctinlines) {ctgraphicalObject graphic = ctinline.getGraphic (); // xmlcursor cursor = graphic.getGraphicData (). newCursor (); Cursor.SelectPath ("./*"); ในขณะที่ (Cursor.TonextSelection ()) {XMLObject XMLObject = Cursor.getObject (); // ถ้าองค์ประกอบลูกอยู่ในรูปแบบ <pic: pic> ถ้า (xmlobject อินสแตนซ์ของ ctpicture) {org.openxmlformats.schemas.drawingml.x2006.picture.ctpicture รูปภาพ = (org.openxmlformats.schemas.drawingml.x2006 // รับแอตทริบิวต์ขององค์ประกอบ imageBundleList.add (picture.getBlipFill (). getBlip (). getEmbed ()); }}}}} // ใช้ ctObject เพื่อบันทึกภาพ // <w: วัตถุ> ฟอร์มถ้า (o อินสแตนซ์ของ ctobject) {ctobject object = (ctobject) o; System.out.println (วัตถุ); xmlcursor w = object.newcursor (); W.SelectPath ("./*"); ในขณะที่ (W.TonextSelection ()) {XMLObject XMLObject = W.GetObject (); if (xmlobject instanceof ctshape) {ctshape shape = (ctshape) xmlobject; imageBundLelist.add (shape.getimagedataarray () [0] .getId2 ()); }}}}} ส่งคืน imageBundLelist; -ก่อนอื่นเราต้องเสนอการห่อหุ้มองค์ประกอบ XML โดย XWPF:
<W: เอกสาร> สอดคล้องกับคลาส XWPFDOCUMENT
<w: เรียกใช้> สอดคล้องกับคลาส XWPFRUN
โดยพื้นฐานแล้วมันสอดคล้องกับเลเยอร์การเรียกใช้เท่านั้น เนื่องจากมีองค์ประกอบของเด็กจำนวนมากของการรันจึงไม่มีการห่อหุ้มและคำจำกัดความใด ๆ ในระดับต่อไปนี้อีกต่อไป
ดังนั้นเราจะได้รับวัตถุ XWPFrun ทั้งหมดที่แปลงเป็นคำจำกัดความ XML: วัตถุ CTR เท่านั้น ในที่สุดใช้ CTR เพื่ออ่านและแยกวิเคราะห์เนื้อหาขององค์ประกอบการเรียกใช้และรับดัชนีของภาพ
สิ่งที่สองที่จะพูดคุยคือคำจำกัดความขององค์ประกอบ XML ทั้งหมด:
เราจะเห็นได้ว่า POI ใช้ XML ที่แยกวิเคราะห์ด้วยเทคโนโลยี XMLBEANS ภายใต้ Apache หากคุณไม่ได้พูดคุยเกี่ยวกับเทคโนโลยีที่เกี่ยวข้องในเชิงลึกคุณต้องเข้าใจประเด็นสำคัญสองประการ:
1: องค์ประกอบทั้งหมดในเอกสาร XML ถูกห่อหุ้มโดย XMLBean และสืบทอดอินเตอร์เฟส XMLObject ดังนั้นคลาสนี้สามารถใช้เพื่อรับองค์ประกอบลูกที่ได้มา;
2: การสำรวจองค์ประกอบผ่าน XMLCursor การได้มาเฉพาะขององค์ประกอบเด็กถูกควบคุมตามแอตทริบิวต์ SelectPath ของวัตถุ XMLCursor เมื่อ SelectPath คือ "./*" มันจะถูกกำหนดให้เป็นองค์ประกอบของเด็ก
ดังนั้นจึงมีการเขียนดังนี้: มันสามารถสำรวจองค์ประกอบลูกขององค์ประกอบปัจจุบันและตรวจสอบประเภทขององค์ประกอบเด็ก:
ctr ctr = run.getctr (); // transultion องค์ประกอบเด็ก xmlcursor c = ctr.newcursor (); // นี่คือการได้รับองค์ประกอบเด็กทั้งหมด: C.SelectPath ("./*"); ในขณะที่ (C.TonextSelection ()) {xmlobject o = c.getObject (); // ถ้าองค์ประกอบลูกอยู่ในรูปแบบ <w: การวาดภาพ> ให้ใช้ ctDrawing เพื่อบันทึกรูปภาพถ้า (อินสแตนซ์ของ ctdrawing)ในที่สุดคุณอาจมีคำถามไม่ได้เป็นองค์ประกอบนี้ <w: การวาด> กำหนดภาพหรือไม่?
ดังนั้น
if (o instanceof ctobject) {ctobject object = (ctobject) o; ... }เงื่อนไขการตัดสินครั้งที่สองใช้สำหรับอะไร?
คุณควรจะเดาได้
ถูกต้อง นอกจาก <w: การวาด> XML ในเอกสาร DOCX ยังสามารถใช้เพื่อกำหนดภาพ
ทำไมมีเพียงสองคนนี้?
เนื่องจากฉันใช้วิธีแรกในการแยกวิเคราะห์ฉันพบว่าภาพบางภาพหายไปดังนั้นฉันจึงพบวิธีที่สอง ... อาจมีมากกว่าสองตัว? ฉันไม่รู้อย่างไรก็ตามไม่มีปัญหาสำหรับฉันในขณะนี้
บางทีคุณอาจเป็นใครที่ฉลาดได้พบกับสถานการณ์ในทางปฏิบัติมากขึ้น?
จากนั้นใช้วิธีการแยกวิเคราะห์ XML ที่กล่าวถึงข้างต้นฉันเชื่อว่าคุณสามารถอ่านได้อย่างถูกต้องและรับค่าดัชนีที่คุณต้องการ
ขยายมันเล็กน้อย หากมี API อื่น ๆ ที่ไม่ได้จัดทำโดย POI เราสามารถนำไปใช้กับเทคโนโลยีการแยกวิเคราะห์ XML ได้หรือไม่? สิ่งนี้ต้องการให้เราสำรวจในทางปฏิบัติ ฉันเชื่อว่าเวลานั้นจะให้คำตอบแก่เรา
โอเคตอนนี้เรามีค่าดัชนีแล้วเราจะได้รับทรัพยากรรูปภาพได้อย่างไร?
POI ให้วิธีการสำเร็จรูป:
มี getPicturedatabyId (รูปภาพสตริง) ในคลาส XWPFDocument;
วิธีการนี้สามารถรับวัตถุ XWPFPICTRUETATE ซึ่งเป็นทรัพยากรรูปภาพ
สำหรับการดำเนินการเฉพาะโปรดดูโพสต์บล็อกและ API ที่เกี่ยวข้องซึ่งจะไม่ถูกนำเสนอในรายละเอียดที่นี่
3. ทดสอบ:
รหัสเพื่อทดสอบโดยใช้ Junit4:
แพ็คเกจ com.szdfhx.reportstatistic.util; นำเข้า org.apache.commons.collections.collectionutils; นำเข้า org.apache.commons.lang.stringutils; นำเข้า org.apache.poi.xwpf.usermodel.xwpfdocument; org.apache.poi.xwpf.usermodel.xwpfparagraph; นำเข้า org.apache.poi.xwpf.usermodel.xwpfpicturedata; นำเข้า org.junit.test; นำเข้า Java.io.fileinputstream; java.util.collections; นำเข้า java.util.list; นำเข้า org.junit.assert.*; คลาสสาธารณะ xwpfutilstest {@test โมฆะสาธารณะ readimageInparapraph () โยน ioexception {inputstream ใน = fileinputstream Document // example.docx "); XWPFDOCUMENT XWPFDOCUMENT = ใหม่ XWPFDOCUMENT (IN); รายการ <XWPFARAGRAPRAPH> PARAGRAPHLIST = XWPFDOCUMENT.GETPARAGRAPHS (); System.out.println ("Image INDEX/T | ชื่อภาพ/t | เนื้อหาของย่อหน้าของข้อความบนภาพ/t"); System.out.pringln ("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- if (collectedUtils.isnotEmpty (ImageBundLelist)) {สำหรับ (String PictureId: ImageBundLelist) {xwpfpicturedata Picturedata = xwpfdocument.getPicturedatabyId (PictureId); System.out.println (pictureId + "/t |" + imagename + "/t |" + lastaragraphtext);}}}}}}}}แสดงผลลัพธ์:
การใช้ชื่อภาพที่นี่หมายความว่าฉันได้รับทรัพยากรที่เกี่ยวข้อง ในความเป็นจริงหากคุณคุ้นเคยกับเนื้อหาของบทความก่อนหน้านี้คุณจะพบว่าชื่อของภาพเป็นชื่อเต็มของภาพทั้งหมดในโฟลเดอร์ Word/Media
ในวัตถุ XWPFPICTURETATA ที่สอดคล้องกันข้อมูลไบนารีของภาพสามารถรับได้ผ่านคุณสมบัติ getData () เพื่อให้คุณสามารถบันทึกลงในฐานข้อมูลหรือโฟลเดอร์ท้องถิ่นของคุณ!
4. อื่น ๆ :
เมื่อพูดถึงเรื่องนี้ปัญหาที่สองที่กล่าวถึงในตอนแรกได้รับการแก้ไขที่นี่
ดังนั้นฉันควรทำอย่างไรกับคำถามแรก?
หากระบบของคุณไม่ต้องการความเร็วสูงคำแนะนำของฉันคือการแปลงเอกสาร DOC เป็นเอกสาร DOCX เพื่อแยกวิเคราะห์ - POI มี API ที่ครบกำหนด
หากคุณต้องการพิจารณาประสิทธิภาพคุณต้องเขียนวิธีการสองชุดเพื่อแยกวิเคราะห์เอกสาร
ดังนั้น ... จะได้รับตำแหน่งสัมพัทธ์ของภาพในเอกสาร Word ประเภทเอกสารได้อย่างไร?
ฉันไม่รู้ ... หรือมาบอกฉันไหม
ในคำที่แยกวิเคราะห์ Java ด้านบนวิธีที่จะได้รับตำแหน่งของรูปภาพในเอกสารคือเนื้อหาทั้งหมดที่ฉันแบ่งปันกับคุณ ฉันหวังว่าคุณจะให้ข้อมูลอ้างอิงและฉันหวังว่าคุณจะสนับสนุน wulin.com มากขึ้น